sf-architect-mcp
# SF Architect MCP
An MCP server that scrapes, indexes, and serves the [Salesforce Architect](https://architect.salesforce.com) documentation locally — enabling fast, offline, RAG-powered search and retrieval for AI coding assistants.
Built with [Model Context Protocol](https://modelcontextprotocol.io), cheerio, SQLite, and Turndown.
---
## What it does
- **Scrapes** `architect.salesforce.com` using fetch + cheerio (the site is server-side rendered)
- **Indexes** content into a local SQLite database with section-aware chunking
- **Searches** using multi-term keyword scoring with section and language filters
- **Supports 17 languages** mirroring the site's locale structure
- **Exposes MCP tools, resources, and prompts** so your AI assistant can navigate and query the docs naturally
---
## Prerequisites
- **Node.js ≥ 18**
- No browser binary required — scraping uses plain HTTP requests
---
## Installation
```bash
git clone https://github.com/morettimarco/salesforce_architect_MCP.git
cd salesforce_architect_MCP
npm install
npm run build
```
The compiled server will be at `dist/index.js`.
---
## Setup in your coding agent
Replace `/absolute/path/to/sf-architect-mcp` with the actual path where you cloned this repo.
### Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"sf-architect": {
"command": "node",
"args": ["/absolute/path/to/sf-architect-mcp/dist/index.js"]
}
}
}
```
### Claude Code (CLI)
```bash
claude mcp add sf-architect node /absolute/path/to/sf-architect-mcp/dist/index.js
```
Or edit `~/.claude/settings.json` (global) or `.claude/settings.json` (project-level):
```json
{
"mcpServers": {
"sf-architect": {
"command": "node",
"args": ["/absolute/path/to/sf-architect-mcp/dist/index.js"]
}
}
}
```
### Cursor
Edit `.cursor/mcp.json` in your project root (or `~/.cursor/mcp.json` for global):
```json
{
"mcpServers": {
"sf-architect": {
"command": "node",
"args": ["/absolute/path/to/sf-architect-mcp/dist/index.js"]
}
}
}
```
### Windsurf
Edit `~/.codeium/windsurf/mcp_config.json`:
```json
{
"mcpServers": {
"sf-architect": {
"command": "node",
"args": ["/absolute/path/to/sf-architect-mcp/dist/index.js"]
}
}
}
```
### VS Code (GitHub Copilot)
Edit `.vscode/mcp.json` in your workspace:
```json
{
"servers": {
"sf-architect": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/sf-architect-mcp/dist/index.js"]
}
}
}
```
---
## First-time setup
Once the server is running in your agent, use the **`scrape-docs` prompt** or call the tool directly:
```
scrape_full → language_filter: "en" (or your preferred language)
```
This fetches the sitemap, scrapes all pages with Puppeteer, converts them to Markdown, and stores them in a local SQLite database at `~/.sf-architect-mcp/sf-architect.db`.
A full English scrape takes roughly 2–3 minutes (≈ 115 pages, 3 concurrent requests).
---
## Tools
| Tool | Description |
|------|-------------|
| `scrape_full` | Wipe the database and re-scrape everything from scratch |
| `scrape_incremental` | Scrape only new, changed, or previously failed pages |
| `search_architect_docs` | Keyword search across indexed content with relevance scoring |
| `read_architect_page` | Read a page's full Markdown content by URL (supports `max_chars`) |
| `read_architect_page_summary` | Lightweight summary: title, headings, word count, 500-char preview |
| `get_section_summary` | Page count, total words, and title list for a section |
| `list_architect_sections` | List all indexed sections with page counts |
| `export_architect_section` | Export a full section to a single Markdown file on disk |
| `get_scrape_status` | Database stats: page counts, sections, last run, pending/failed URLs |
---
## Resources
Attach these to your conversation context for orientation:
| URI | Description |
|-----|-------------|
| `sf-architect://guide/usage` | Recommended workflows and tool usage tips |
| `sf-architect://data/languages` | All supported language codes with display names |
| `sf-architect://data/sections` | Live section index with current page counts |
---
## Prompts
Pre-built workflow templates:
| Prompt | Arguments | What it does |
|--------|-----------|--------------|
| `scrape-docs` | `mode`: `full` or `incremental` | Presents available languages, asks which to scrape, then runs the appropriate tool |
| `research-topic` | `topic`: string | Searches, summarizes relevant pages, and synthesizes findings with citations |
| `export-section` | `section`: string | Verifies the section exists, shows a summary, then exports to Markdown |
---
## Supported languages
| Code | Language |
|------|----------|
| `en` | English (default) |
| `de` | German |
| `fr` | French |
| `jp` | Japanese |
| `zh-cn` | Chinese (Simplified) |
| `zh-tw` | Chinese (Traditional) |
| `dk` | Danish |
| `es` | Spanish |
| `fi` | Finnish |
| `it` | Italian |
| `kr` | Korean |
| `nl` | Dutch |
| `no` | Norwegian |
| `pt-br` | Portuguese (Brazil) |
| `ru` | Russian |
| `se` | Swedish |
| `es-mx` | Spanish (Mexico) |
| `all` | All languages |
> **Note:** Not all languages are available for all sections. The sitemap at scrape time determines what's actually published.
---
## Configuration
The database is stored at `~/.sf-architect-mcp/sf-architect.db` by default.
Override with an environment variable:
```bash
SF_ARCHITECT_DB_DIR=/custom/path node dist/index.js
```
Exported markdown files go to `~/.sf-architect-mcp/exports/{section}-{language}.md` unless you specify a custom path.
---
## Architecture
```
src/
├── index.ts # MCP server — tools, resources, prompts
├── scraper.ts # fetch + cheerio scraper, concurrency pool
├── sitemap.ts # Sitemap fetching and URL filtering
├── types.ts # Shared TypeScript types
├── db/
│ ├── database.ts # sql.js SQLite, persistence, schema
│ ├── ingest.ts # Page upsert, chunk sync, scrape run tracking
│ └── queries.ts # Search, read, export, stats
└── utils/
├── chunker.ts # Section-aware text chunking (1500 chars, 200 overlap)
└── url-utils.ts # Language detection from URL path segments
```
**Key design decisions:**
- **fetch + cheerio** — the site is fully server-side rendered, no headless browser needed. ~10x faster and cross-platform with zero native dependencies
- **sql.js (WASM SQLite)** — in-process, zero native dependencies, serialized to disk after every 10 pages
- **Section-aware chunking** — detects both Markdown headings and bold-text markers (`**Definition:**`) which the site uses instead of semantic HTML headings
- **LRU cache** on search results (500 entries, 5-minute TTL)
- **Content hash comparison** for incremental scraping — only re-indexes pages whose content has actually changed
---
## License
MIT
TDQS
Scored across 9 tools
Most tools target distinct operations (scrape, search, read, export, status). The only real overlap is between get_section_summary and list_architect_sections, which both return section page counts and titles, and read_architect_page vs read_architect_page_summary, though the latter pair is clearly differentiated by the descriptions.
All nine tools follow a consistent snake_case verb_noun pattern (scrape_full, search_architect_docs, read_architect_page, export_architect_section, get_scrape_status). Resources and prefixes (architect, section, scrape) are used predictably.
Nine tools is well-scoped for a documentation indexing/retrieval server, covering ingestion (2 scrape modes), discovery (sections), retrieval (search, read, read summary), export, and status with no redundancy.
The surface covers the full lifecycle: full/incremental ingestion, status monitoring, section listing and summaries, search, page reading, and export. No obvious dead ends, and scrape_full handles the reset case that a delete tool would otherwise cover.