The GeekMidst MCP Server
An internal product: a public, read-only MCP server that gives AI assistants citable access to GeekMidst guides and calculators. How it works and how to connect.

This is an illustrative blueprint. It is a reference architecture, not a write-up of a specific client project; outcomes depend on your data and setup.
GeekMidst runs a public Model Context Protocol (MCP) server at the /mcp endpoint on this website. It lets AI assistants search and read our published guides, run the same ROI model as our calculator, and score our self-assessments, with search and page results that cite their page URLs. This page explains why we built it, how it works, and how you can check it yourself.
Status
- Live on this website, public and read-only.
- Tested in the build environment with the TypeScript SDK v1 client (
@modelcontextprotocol/sdk1.32.1), the TypeScript SDK v2 client (@modelcontextprotocol/client2.3.1) in both legacy and 2026-07-28 modes, the Python SDK (mcp2.3.0) and MCP Inspector CLI 2.12.0. - Built-in self-test that the site owner runs on the live host, covering more than 20 protocol checks, including an HTTP check through the web server.
Problem, objectives and scope
AI assistants are asked about Salesforce, Marketing Cloud, Data 360, Braze and MCP, and can answer from stale or unsourced material. We wanted assistants to be able to use our published guides accurately and with citations, without exposing anything private.
Objectives:
- Give any MCP-capable assistant access to published pages, with URLs it can cite.
- Offer the website's calculators and assessments as tools, with the same logic as the web versions.
- Expose nothing that is not already public, and make it impossible to change anything.
- Work with as many clients as possible across both protocol eras.
In scope: published pages, the integration catalogue, the ROI calculator and the self-assessments. Out of scope: drafts, enquiries, any visitor data, and any connection to Salesforce, Braze or client systems.
Technology stack
| Layer | Choice |
|---|---|
| Application | The existing PHP website application, sharing its content store |
| Transport | Streamable HTTP on a single /mcp endpoint, plain JSON responses, no SSE stream |
| Protocol | JSON-RPC 2.0; 2026-07-28 (stateless, server/discover) and 2025-11-25, 2025-06-18 and 2025-03-26 (initialize handshake) |
| Access | Public, no authentication; origin validation for browser clients; per-address rate limit |
| Logging | Anonymous request log kept for 90 days, with no tool arguments |
| Testing | TypeScript SDK v1 and v2 clients, Python SDK, MCP Inspector CLI, plus the admin self-test |
GeekMidst website MCP server
Implemented and tested by GeekMidst
Select a component to see what it is responsible for and how data moves to and from it.
Components and data flows (text version)
| Component | Type | Responsibility |
|---|---|---|
| AI hostany MCP-capable application | AI and agents | The visitor's AI application. It decides when to call a tool or read a resource and shows the results to its user. |
| MCP clientSDK, Inspector or built into a host | AI and agents | Sends one JSON-RPC 2.0 message per HTTP POST, using either the initialize handshake or 2026-07-28 request metadata. |
| /mcp endpointorigin check and rate limit | Identity, policy and governance | Checks the Origin header for browser clients, applies a per-address rate limit and request size limit, and answers GET with 405 because there is no SSE stream. |
| JSON-RPC dispatcherlegacy and 2026-07-28 eras | Integration layer | Selects the era per request, validates headers and _meta, rejects batches, and routes to tools, resources or prompts. Returns plain JSON. |
| Anonymous request logkept 90 days | Data and analytics | Records method, tool, outcome, timing, client name and a hashed address. Tool arguments are not stored. |
| Admin self-test20+ protocol checks | People | Run by the site admin on the live host. Exercises negotiation, discovery, validation, errors and an HTTP check through the web server. |
| Read-only toolssix tools, all annotated read-only | Integration layer | search_site, get_page, list_pages, calculate_sales_roi, score_assessment and list_integrations. Each validates input against its schema. |
| Resourcesgm://page/{path} and site indexes | Integration layer | Every published page as a resource, plus the site overview, the integration catalogue and the architecture index. |
| Promptssix review and planning templates | Integration layer | User-chosen templates such as integration_plan and troubleshooting, each with declared arguments. |
| Published pages | Data and analytics | Only content already published on this website. Unpublished drafts are not exposed. |
| Calculators and assessments | Data and analytics | The same ROI model and self-assessment scoring that the website's own tools use. |
Data flows
- AI host → MCP client: tool and resource calls. The host passes the model's chosen calls to its MCP client.
- MCP client → /mcp endpoint: HTTPS POST, JSON-RPC 2.0. Streamable HTTP with plain JSON responses. A blocked origin gets 403; too many requests get 429 with Retry-After.
- /mcp endpoint → JSON-RPC dispatcher: accepted request. Requests that pass origin, size and rate checks reach the dispatcher. Malformed JSON gets a parse error.
- JSON-RPC dispatcher → Anonymous request log: request outcome. Method, tool name, outcome and timing are logged after each request, without arguments.
- Admin self-test → /mcp endpoint: HTTP self-check. The self-test calls the live endpoint through the web server, so proxy or rewrite problems show up as failures.
- JSON-RPC dispatcher → Read-only tools: tools/call. Unknown tools are a protocol error; invalid input returns a tool error the model can correct.
- JSON-RPC dispatcher → Resources: resources/read. A missing resource returns an error, never empty contents.
- JSON-RPC dispatcher → Prompts: prompts/get. A missing required argument returns -32602.
- Read-only tools → Published pages: search and read. Search returns cited passages with URLs; long pages are truncated.
- Read-only tools → Calculators and assessments: run model. ROI and assessment results are computed from the stated inputs; omitted inputs use the website's example values.
- Resources → Published pages: page text. Page text is returned as markdown under its gm://page URI.
Implementation approach
We added the server to the website application rather than running a separate service, so it reads exactly what visitors see and is unpublished the moment a page is. Tool, resource and prompt definitions live in one place, and the connection details on this page are generated from those same definitions.
The dispatcher handles both eras on one endpoint, as the spec allows: an initialize request selects legacy behaviour; a request carrying _meta with protocol version 2026-07-28 is served statelessly, with MCP-Protocol-Version, Mcp-Method and Mcp-Name checked against the body. Each tool's input is checked against its JSON Schema, and unknown fields are rejected. Every tool carries readOnlyHint: true.
Challenges, solutions and trade-offs
Design decisions
| Challenge | What we did | Trade-off |
|---|---|---|
| Hosting on ordinary PHP hosting | Stateless design with no sessions; any request can be answered on its own | No server-initiated messages or subscriptions |
| Streaming support | Plain JSON for every response, which clients must accept; GET answers 405 | No progress updates for long calls, so tools are kept fast |
| Authentication | None, because the server only returns published content | Rate limits and origin checks are the only access controls; nothing private can ever be added without redesign |
| Bad input from models | Strict schemas, with validation errors returned as tool errors | A model may need a second attempt after a validation error |
| Clients on different eras | Dual-era support on one endpoint | Two code paths to test after every spec change |
Deliverables
- The
/mcpendpoint with six read-only tools:search_site,get_page,list_pages,calculate_sales_roi,score_assessmentandlist_integrations. - Resources for every published page (
gm://page/{path}) plusgm://site/overview,gm://catalogue/integrationsandgm://architecture/index. - Six prompts: architecture_assessment, integration_plan, data_readiness_review, campaign_review, troubleshooting and implementation_plan.
- The admin self-test and the anonymous request log.
- The connection guide below.
Outcomes
We claim only what you can verify:
- Anyone can connect to the
/mcpendpoint and list and call the tools, with no account. - Every tool is annotated read-only, and none can change website content.
- It was tested with the clients listed under Status, in both protocol eras.
Try it
The details below are generated live from the server's own definitions.
Connect to the GeekMidst MCP server
- Endpoint
https://geekmidst.com/GeekMidst/mcp- Transport
- Streamable HTTP (JSON responses, no SSE stream)
- Protocol versions
- 2026-07-28 (stateless) and 2025-11-25, 2025-06-18, 2025-03-26 (initialize handshake)
- Authentication
- None: public, read-only content only
- Server version
- 8.0.0
- Last self-test
- Not run on this host yet
Tools
| Tool | What it does | Access |
|---|---|---|
search_site | Search published GeekMidst pages (services, solutions, architecture guides, Salesforce product guides, articles) and return the best-matching passages with their URLs. Use it before answering questions about Salesforce, Marketing Cloud, Data 360, Braze or MCP integration so answers can cite a page. | Read-only |
get_page | Return the text of one published GeekMidst page by its path, for example /solutions/salesforce-braze/ or architecture/data-360. Long pages are cut at about 14,000 characters. | Read-only |
list_pages | List published pages of one type with their URLs and summaries. Types: service, solution, case_study, architecture, product, blog, comparison, resource, industry, location, page. | Read-only |
calculate_sales_roi | Run the same three-scenario sales ROI model as the calculator on the GeekMidst website. Results are estimates from the stated assumptions, not forecasts. Omitted inputs use the website example values, which are not benchmarks. | Read-only |
score_assessment | Score one of the website self-assessments from answer indexes (0 = first option). Call with only "assessment" to get the questions and options first. Assessments: mc_health, data_readiness, integration. | Read-only |
list_integrations | List the published entries of the GeekMidst MCP and integration catalogue with their status (planned, in development, implemented, tested, available, deprecated). Vendor servers are listed separately from GeekMidst servers; a listing is not an endorsement or affiliation. | Read-only |
Prompts
architecture_assessment: Review a Salesforce architecture against GeekMidst reference architectures and list risks, gaps and next steps.integration_plan: Plan an integration between Salesforce and another system: pattern, data ownership, error handling and testing.data_readiness_review: Assess whether customer data is ready for Data 360, identity resolution and activation.campaign_review: Analyse a lifecycle or campaign design (Marketing Cloud or Braze) for targeting, consent, measurement and operational risks.troubleshooting: Work through a Salesforce, Marketing Cloud or integration problem step by step using GeekMidst guides.implementation_plan: Draft phases, prerequisites, tests and risks for a Salesforce, Data 360, Braze or MCP implementation.
Resources
Every published page as gm://page/{path}, plus gm://site/overview, gm://catalogue/integrations and gm://architecture/index.
Client configuration
Many MCP clients accept a remote server entry like this. The exact format depends on the client; check its documentation.
{
"mcpServers": {
"geekmidst": {
"type": "http",
"url": "https://geekmidst.com/GeekMidst/mcp"
}
}
}import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(new StreamableHTTPClientTransport(new URL("https://geekmidst.com/GeekMidst/mcp")));
const { tools } = await client.listTools();
const res = await client.callTool({ name: "search_site", arguments: { query: "Salesforce and Braze consent sync" } });Limitations
- No write tools. It cannot send messages, create records or change anything.
- No client systems. It does not connect to Salesforce, Marketing Cloud, Data 360, Braze or any client system, and has not been tested against them.
- No SSE. There are no streams, subscriptions or progress notifications.
- No authentication. That is deliberate for public content, and it means the design is not a template for private data. For that, see MCP security and authorisation.
- Long pages are cut short when read through
get_page.
Lessons learned
- Plain JSON goes a long way. For fast, read-only tools, skipping SSE removed a class of hosting problems.
- Support the legacy handshake. The official TypeScript SDK client and the MCP Inspector default to it, so dual-era support mattered more than being modern-only.
- Test through the real web server. URL rewrites, proxies and buffering only show their effects on the live path, which is why the self-test includes an HTTP check through the web server.
- Good tool descriptions matter. Models choose tools from their descriptions, so we wrote them for the model, not for us.
- Separate content from protocol. Keeping tool logic apart from JSON-RPC handling made both easier to test.
The same principles shape our MCP server development work. For the general pattern, read the MCP host, client and server architecture and the MCP architecture guide. Designs for Salesforce or Braze on MCP integrations are proposed, not built.
Related
MCP server development
Build a server for your own systems
→MCP integration consulting
Vendor servers, governance and rollout
→MCP integrations
Proposed MCP designs across products
→MCP security and governance
Controls for servers that touch private data
→Sources
- https://modelcontextprotocol.io/specification/2025-11-25/basic/transports
- https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http
- https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning
- https://modelcontextprotocol.io/specification/2026-07-28/server/tools
- https://modelcontextprotocol.io/docs/learn/architecture
Want a server like this for your own content?
We can design a read-only MCP server for your documentation or knowledge base, then plan any controlled actions.




