Ingest and process emails, take calendar actions, build rich spreadsheets.
Declawed: A Configurable, Promptable AI Mail Assisty Kitty
A local Model Context Protocol (MCP) server and LLM integration platform. Built to connect to LLM APIs - be itClaude Desktop, others... or locally hosted models. Executes your prompts to manage your mail, while you... watch Fellini films, solve climate change, sip Mai Tais, or.... whatever.
Ssssimple. Siamsese, if you please.... Eats the blue-plate-crustacean for breakfast.
Infinitely mod-able. Dead simple. Privacy centric.
Scope
Current implementation contemplates: Claude Desktop + Custom, Local Model Context Protocol Server + Commercial SMTP Server (MX'config’d properly) + your DNS-config’d XXX.YYY
1. Install: Node.js
Node.js v16 or higher must be installed.
node --version
npm --version
If not installed, download from nodejs.org.
2. Initialize the Project
mkdir assistant
cd assistant
npm init -y
3. Install Dependencies
npm install @modelcontextprotocol/sdk zod@3 googleapis
npm install -D @types/node typescript
Create the source directory and entry file:
mkdir src
touch src/index.ts
4. Configure the Project
4a. Update package.json
Set the module type, binary entry, and build scripts:
{
"type": "module",
"bin": {
"assistant": "./build/index.js"
},
"scripts": {
"build": "tsc && chmod 755 build/index.js",
"auth": "npm run build && node build/auth.js"
},
"files": ["build"]
}
4b. Create tsconfig.json in the project root
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
5. Write the Server Code
The server source lives in src/index.ts. It registers three tools and one prompt with the MCP server:
fetch_new_emails-- fetches unread Gmail messagesdelete_emails-- trashes messages by IDappend_to_summary-- logs classified emails tosummary.jsonreview_emails(prompt) -- feeds Claude the classification instructions
The auth helper lives in src/auth.ts, used only for the one-time OAuth setup.
6. Set Up Google Cloud Credentials
6a. Create a Google Cloud Project
- Go to Google Cloud Console
- Sign in with the Google account that owns the target Gmail
- Click the project dropdown (top-left) and select New Project
- Name it (e.g.,
assistant-mcp) and click Create - Select the new project from the dropdown
6b. Enable the Gmail API
- Go to APIs & Services > Library (direct link)
- Search for Gmail API
- Click it, then click Enable
6c. Configure the OAuth Consent Screen
- Go to Google Auth Platform > Branding (or APIs & Services > OAuth consent screen)
- Set user type to External, click Create
- Fill in app name, support email, and developer contact email
- Save and continue
6d. Add the Gmail Scope
- Go to Google Auth Platform > Data Access (or the Scopes page)
- Click Add or remove scopes
- Add:
https://www.googleapis.com/auth/gmail.modify - Save
6e. Add Yourself as a Test User
- Go to Google Auth Platform > Audience
- Add your Gmail address as a test user
6f. Create OAuth Client Credentials
- Go to Google Auth Platform > Clients (or APIs & Services > Credentials)
- Click Create Client (or + Create Credentials > OAuth client ID)
- Application type: Desktop app
- Name it anything (e.g.,
Assistant MCP Desktop) - Click Create
- Download the JSON file
- Rename it to
credentials.json - Move it to the project root:
/Users/kjannette/assistant/credentials.json
7. Authorize Your Gmail Account
Build the project and run the auth script:
npm run auth
This will:
- Print a URL -- open it in your browser
- Sign in with your Google account and click Allow
- You'll land on a "localhost refused to connect" page (this is normal)
- Copy the entire URL from the browser address bar
- Paste it into the terminal prompt
- The script extracts the auth code and saves
token.json
You only need to do this once. The token auto-refreshes.
8. Build the Server
npm run build
This compiles src/*.ts into build/*.js.
9. Write the Classification Prompt
Create a file called classify-emails.txt in the project root. This file contains the plain-text instructions that tell Claude how to classify your emails.
Tips for writing the prompt:
- Use clear, explicit category definitions with example language for each
- Handle ambiguous cases (e.g., "If an email both acknowledges receipt AND requests action, classify it as B")
- Define the exact actions to take for each category (delete, summarize, etc.)
- Specify what fields to include in summaries
- Keep it in plain text -- no JSON or special formatting needed
- The file is loaded at runtime, so you can edit it without rebuilding the server
File location: Must be at the project root as classify-emails.txt.
10. Configure Claude Desktop
Edit the Claude Desktop config file:
code ~/Library/Application\ Support/Claude/claude_desktop_config.json
Add the assistant server to the mcpServers object:
{
"mcpServers": {
"assistant": {
"command": "/ABSOLUTE/PATH/TO/node",
"args": [
"/Users/kjannette/assistant/build/index.js"
]
}
}
}
Replace /ABSOLUTE/PATH/TO/node with the output of which node.
11. Restart Claude Desktop
Fully quit Claude Desktop (Cmd+Q, not just close the window) and reopen it. The assistant server should now appear under Connectors in the chat input.
Usage Guide
Prompt Loader
The server reads classify-emails.txt from the project root at runtime. To change classification behavior, edit that file directly -- no rebuild required. The updated instructions take effect on the next tool call.
MCP Prompt: review_emails
A registered MCP prompt available in Claude Desktop's Connectors menu. When invoked, it feeds Claude the full contents of classify-emails.txt as a user message, giving Claude all the classification criteria before it calls any tools. This is the recommended way to trigger the workflow -- it ensures Claude has the complete instructions every time.
fetch_new_emails Enrichment
Every time fetch_new_emails is called, the classification instructions from classify-emails.txt are appended to the response alongside the email data. This means Claude always sees the rules with the data, even if the review_emails prompt was not explicitly invoked. Belt and suspenders.
Running the Workflow
- Open Claude Desktop
- Type: "Review my inbox" (or invoke the
review_emailsprompt from Connectors) - Claude will:
- Call
fetch_new_emailsto retrieve unread messages - Classify each email as A, B, C, or D using the prompt instructions
- Call
delete_emailsfor categories A and C - Call
append_to_summaryfor categories B and D
- Call
- Results are displayed in the chat and saved to
summary.json
Key Commands
| Command | Purpose |
|---|---|
npm run build |
Recompile after editing src/index.ts |
npm run auth |
Re-authorize Gmail (only if token.json deleted/expired) |
| Cmd+Q Claude Desktop, reopen | Pick up server changes after a rebuild |
Project Structure
assistant/
├── src/
│ ├── index.ts # MCP server source (tools + prompt)
│ └── auth.ts # One-time OAuth setup script
├── build/
│ ├── index.js # Compiled server (Claude Desktop runs this)
│ └── auth.js # Compiled auth script
├── classify-emails.txt # Classification prompt (plain text, edit anytime)
├── credentials.json # Google OAuth client credentials (from Cloud Console)
├── token.json # Gmail access/refresh token (auto-generated)
├── summary.json # Output file where B/D emails are logged
├── package.json # Project config and scripts
├── tsconfig.json # TypeScript compiler config
└── README.md # This file