← back to George Mcp
Add account param to all george MCP tools (5-account routing)
a8aaa436d634fa3b03ac6f1247915405302c89bb · 2026-05-18 14:48:41 -0700 · Steve Abrams
Files touched
Diff
commit a8aaa436d634fa3b03ac6f1247915405302c89bb
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon May 18 14:48:41 2026 -0700
Add account param to all george MCP tools (5-account routing)
---
index.js | 48 ++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/index.js b/index.js
index cb7a5a3..93cd4d3 100755
--- a/index.js
+++ b/index.js
@@ -63,6 +63,20 @@ async function george(path, { method = "GET", query, body } = {}) {
return data;
}
+// George serves five Gmail accounts. Every tool below accepts an optional
+// `account` param; omitted => steve-office. Keys match George's resolveAccount().
+const ACCOUNTS = ["steve-office", "info", "steve-personal", "stevesclaude", "agentabrams"];
+const ACCOUNT_PROP = {
+ account: {
+ type: "string",
+ enum: ACCOUNTS,
+ description:
+ "Which Gmail account to act on. Default 'steve-office' (steve@designerwallcoverings.com). " +
+ "Others: 'info' (info@designerwallcoverings.com), 'steve-personal' (steveabramsdesigns@gmail.com), " +
+ "'agentabrams' (theagentabrams@gmail.com), 'stevesclaude'.",
+ },
+};
+
const TOOLS = [
{
name: "gmail_health",
@@ -93,6 +107,7 @@ const TOOLS = [
description: "Comma-separated label IDs to restrict the search.",
},
pageToken: { type: "string" },
+ ...ACCOUNT_PROP,
},
additionalProperties: false,
},
@@ -111,6 +126,7 @@ const TOOLS = [
maximum: 100,
default: 10,
},
+ ...ACCOUNT_PROP,
},
required: ["query"],
additionalProperties: false,
@@ -122,7 +138,7 @@ const TOOLS = [
"Fetch a single Gmail message by id (full body + headers + attachment metadata).",
inputSchema: {
type: "object",
- properties: { id: { type: "string" } },
+ properties: { id: { type: "string" }, ...ACCOUNT_PROP },
required: ["id"],
additionalProperties: false,
},
@@ -130,12 +146,16 @@ const TOOLS = [
{
name: "gmail_list_labels",
description: "List all Gmail labels on the connected account.",
- inputSchema: { type: "object", properties: {}, additionalProperties: false },
+ inputSchema: {
+ type: "object",
+ properties: { ...ACCOUNT_PROP },
+ additionalProperties: false,
+ },
},
{
name: "gmail_send",
description:
- "Send an email from the connected DW Gmail account (steve@designerwallcoverings.com by default). Body is HTML. To reply IN-THREAD to a previous George-sent message, pass `replyToMessageId` (Gmail message id) — George will resolve the thread, set In-Reply-To/References, and prefix Re: as needed. `subject` becomes optional in that case.",
+ "Send an email from one of George's DW Gmail accounts (steve-office / steve@designerwallcoverings.com by default — pass `account` to send from another). Body is HTML. To reply IN-THREAD to a previous George-sent message, pass `replyToMessageId` (Gmail message id) — George will resolve the thread, set In-Reply-To/References, and prefix Re: as needed. `subject` becomes optional in that case.",
inputSchema: {
type: "object",
properties: {
@@ -156,6 +176,7 @@ const TOOLS = [
type: "string",
description: "RFC Message-Id header value (with angle brackets) of the message being replied to. Bypasses replyToMessageId resolution.",
},
+ ...ACCOUNT_PROP,
},
required: ["to", "body"],
additionalProperties: false,
@@ -172,6 +193,7 @@ const TOOLS = [
body: { type: "string", description: "HTML body" },
cc: { type: "string" },
bcc: { type: "string" },
+ ...ACCOUNT_PROP,
},
required: ["to", "subject", "body"],
additionalProperties: false,
@@ -181,7 +203,11 @@ const TOOLS = [
name: "gmail_profile",
description:
"Return profile info (email address, total messages, total threads) for the connected account.",
- inputSchema: { type: "object", properties: {}, additionalProperties: false },
+ inputSchema: {
+ type: "object",
+ properties: { ...ACCOUNT_PROP },
+ additionalProperties: false,
+ },
},
];
@@ -194,6 +220,9 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }))
server.setRequestHandler(CallToolRequestSchema, async (req) => {
const { name, arguments: args = {} } = req.params;
+ // account flows to George as ?account= on GETs and inside the body on POSTs
+ // (George's resolveAccount() reads req.query.account || req.body.account).
+ const account = args.account;
try {
let data;
switch (name) {
@@ -207,19 +236,22 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
maxResults: args.maxResults ?? 25,
labelIds: args.labelIds,
pageToken: args.pageToken,
+ account,
},
});
break;
case "gmail_search":
data = await george("/api/search", {
- query: { q: args.query, maxResults: args.maxResults ?? 10 },
+ query: { q: args.query, maxResults: args.maxResults ?? 10, account },
});
break;
case "gmail_get_message":
- data = await george(`/api/messages/${encodeURIComponent(args.id)}`);
+ data = await george(`/api/messages/${encodeURIComponent(args.id)}`, {
+ query: { account },
+ });
break;
case "gmail_list_labels":
- data = await george("/api/labels");
+ data = await george("/api/labels", { query: { account } });
break;
case "gmail_send":
data = await george("/api/send", { method: "POST", body: args });
@@ -228,7 +260,7 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
data = await george("/api/drafts", { method: "POST", body: args });
break;
case "gmail_profile":
- data = await george("/api/profile");
+ data = await george("/api/profile", { query: { account } });
break;
default:
throw new Error(`Unknown tool: ${name}`);
← 4834576 george-mcp: derive BASE_PATH_PREFIX — empty for direct-port
·
back to George Mcp
·
gmail send: pass X-Send-Approval from GEORGE_EXTERNAL_SEND_T e616a1b →