Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,6 @@ transform.js
*.dump
*.sql.gz
*.backup

# Internal ops doc — not for the public repo
ForgeMind_CICD_Setup_Guide.pdf
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,52 @@ In the **Meta dashboard** → **WhatsApp → Configuration → Webhook → Edit*

---

## 🔌 Build agents from Claude (MCP server)

ForgeChat ships an **MCP server** so you can **build and manage your WhatsApp AI agents by chatting with Claude** (Claude Desktop, or any MCP client) — it asks what you need, looks up your real WhatsApp numbers, AI models, Google Sheets, media and templates, and creates a fully-configured agent for you. No dashboard required.

### Step 1 — Turn it on and get a key
In ForgeChat, open **Settings → MCP Tools**:
1. Flip the **master switch** on, and enable the **capabilities** you want (discovery, create/update agents, manage tools, delete).
2. Click **Generate key** and copy the `fck_live_…` value — it's shown **once**.

### Step 2 — Connect Claude (pick one)

**A) Remote — just a URL (easiest)**
The MCP Tools page shows a ready-to-paste connect URL:

```
https://your-domain/api/mcp/http/<your-key>
```

In Claude (web/desktop/mobile) → **Settings → Connectors → Add custom connector** → paste that URL. Done.

**B) Local — run the bundled server**
Use the server in [`mcp-server/`](mcp-server/) (`npm install` once), then add this to your `claude_desktop_config.json`
(macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`, Windows: `%APPDATA%\Claude\claude_desktop_config.json`):

```json
{
"mcpServers": {
"forgechat-agents": {
"command": "node",
"args": ["/path/to/ForgeChat/mcp-server/src/index.js"],
"env": {
"FORGECHAT_API_URL": "https://your-domain/api/mcp/v1",
"FORGECHAT_API_KEY": "fck_live_PASTE_YOUR_KEY"
}
}
}
}
```

### Step 3 — Use it
Fully quit and reopen Claude, then say **“create a ForgeChat agent”** — it walks you through the setup questions and builds the agent. Each capability is gated by the toggles in **Settings → MCP Tools** (a disabled one returns a clear error), and the key can be revoked any time from the same page.

> Replace `your-domain` with wherever ForgeChat is hosted. The bearer key works over the internet; your ForgeChat login cookie is never involved. See [`mcp-server/README.md`](mcp-server/README.md) for the full tool list and debugging tips.

---

## 🔄 Keeping it running

**Update to the latest version** (run on your server, inside the `ForgeChat` folder):
Expand Down
6 changes: 3 additions & 3 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Keep all eight design principles regardless of flow.

---

## Phase 4 — Build the agent in ForgeChat over MCP (optional)
## Phase 4 — Build the agent in ForgeChat over MCP

Phases 1–3 produce the **system prompt**. If a ForgeChat **MCP connector** is connected, you can also **create and configure the agent directly in ForgeChat** instead of pasting the prompt by hand — Claude drives the build through the MCP tools.

Expand All @@ -130,12 +130,12 @@ Build flow:
4. Trigger: `"any"` (every message) or `"keyword"` (ask keyword, match type exact/contains/starts, case sensitivity, session minutes — default 30).
5. Inbound understanding: set `transcribeAudio:true` to transcribe voice notes (needs an OpenAI key), `acceptImages:true` to let it see images (pick a vision-capable model, e.g. GPT-4o / Claude).
6. Tools:
- **Google Sheets** (per connected Google account): `list_google_accounts` → `search_spreadsheets` (with that `googleAccountId`) → `list_sheet_tabs` → ask which ops (read/append/update), then `add_google_sheets_tool` (`googleAccountId` + spreadsheet + tab + ops).
- **Google Sheets** (per connected Google account): `list_google_accounts` → `search_spreadsheets` (with that `googleAccountId`) → `list_sheet_tabs` → if the agent will LOG rows, call `read_sheet_values` (range `A1:Z1`) to read the real header row and map fields to the exact column names. Ask which ops to allow — read / append / update / **upsert** — then `add_google_sheets_tool` (`googleAccountId` + spreadsheet + tab + ops). **For logging a contact's data, prefer `upsert`:** it finds the contact's existing row by a key column (e.g. phone number) and updates only the columns you name, or adds a new row if none exists — so a contact never gets duplicate rows and you never track row numbers or column order.
- **HTTP request** (call an external API / device / webhook): `add_http_tool` with method + URL (use `{name}` for path params) + static auth headers + the params the AI fills (each: name, location path/query/body/header, type, description, required).
7. Media groups (optional): for each, a "when to send" **description** + media (`list_media`) and/or an approved template (`list_templates` → `get_template` to confirm content before using its id).
8. Summarize the full config, get a "yes", then `create_agent`; attach any tools; report the new agent id and offer to activate it (Go Live).

**MCP tools available** — discovery: `list_wa_accounts`, `list_models`, `list_google_accounts`, `search_spreadsheets`, `list_sheet_tabs`, `list_media`, `list_templates`, `get_template`, `list_agents`, `get_agent`. Mutations: `create_agent`, `update_agent`, `add_google_sheets_tool`, `add_http_tool`, `add_tool`, `update_tool`, `delete_tool`, `delete_agent`. The master switch + per-capability toggles in Admin Settings → MCP Tools gate what's allowed (a disabled capability returns 403); always confirm destructive actions first.
**MCP tools available** — discovery: `list_wa_accounts`, `list_models`, `list_google_accounts`, `search_spreadsheets`, `list_sheet_tabs`, `read_sheet_values`, `list_media`, `list_templates`, `get_template`, `list_agents`, `get_agent`. Mutations: `create_agent`, `update_agent`, `add_google_sheets_tool`, `add_http_tool`, `add_tool`, `update_tool`, `delete_tool`, `delete_agent`. The master switch + per-capability toggles in Admin Settings → MCP Tools gate what's allowed (a disabled capability returns 403); always confirm destructive actions first.

**Constraints to respect** (the server enforces them too): OpenAI / Anthropic providers only; one active agent per WhatsApp number; a keyword-triggered active agent needs a keyword; context window 1–100 messages; max tool iterations 1–20; trigger session 1–1440 minutes; `acceptImages` requires a vision-capable model.

Expand Down
7 changes: 7 additions & 0 deletions backend/db/migrations/056_agent_accept_images.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- 056_agent_accept_images.sql
-- Per-agent toggle: when on, the agent "sees" an inbound WhatsApp image by
-- passing the image to its (vision-capable) LLM along with any caption. Mirrors
-- transcribe_audio (migration 054). Additive + idempotent.

ALTER TABLE coexistence.agents
ADD COLUMN IF NOT EXISTS accept_images BOOLEAN NOT NULL DEFAULT FALSE;
25 changes: 25 additions & 0 deletions backend/db/migrations/057_mcp.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- 057_mcp.sql
-- External MCP access: bearer API keys + a singleton settings row (master switch
-- + per-capability toggles). Mirrors services/mcpService.ensureMcpTables().
-- Additive + idempotent.

CREATE TABLE IF NOT EXISTS coexistence.mcp_api_keys (
id BIGSERIAL PRIMARY KEY,
label TEXT NOT NULL,
key_prefix TEXT NOT NULL,
key_last4 TEXT NOT NULL,
key_hash TEXT NOT NULL UNIQUE, -- sha256(plaintext) hex
is_enabled BOOLEAN NOT NULL DEFAULT TRUE,
last_used_at TIMESTAMPTZ,
created_by BIGINT REFERENCES coexistence.forgecrm_users(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE TABLE IF NOT EXISTS coexistence.mcp_settings (
id INT PRIMARY KEY DEFAULT 1 CHECK (id = 1),
master_enabled BOOLEAN NOT NULL DEFAULT FALSE,
capabilities JSONB NOT NULL DEFAULT '{"discovery":true,"create_agent":true,"update_agent":true,"manage_tools":true,"delete":true}'::jsonb,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

INSERT INTO coexistence.mcp_settings (id) VALUES (1) ON CONFLICT DO NOTHING;
Loading