marketsharp-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@marketsharp-mcp Find recent inquiries for the Johnson contact"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
marketsharp-mcp
MCP server for the MarketSharp CRM REST API
(https://restapi.marketsharpm.com, API version 2.0). It gives an AI assistant
read access to a home-improvement contractor's contacts, inquiries (leads),
appointments, jobs, notes and reference lists. Every tool is read-only.
Maintained by WYRE AI. It runs as a stdio server locally or as a stateless Streamable HTTP server behind a gateway.
Credentials
MarketSharp uses application authentication: the server exchanges your
Company ID, API key and API secret at POST /token for a short-lived bearer
token, caches it per credential set, and refreshes it on expiry or a 401.
Variable | Gateway header | Required | Where to find it |
|
| yes | Shown under your username, top right in MarketSharp |
|
| yes | Admin → Apps & Add-ons Setup → API maintenance → Create New API Key |
|
| yes | Issued with the API key. If there's no secret, MarketSharp support has to turn on API access |
|
| no | MarketSharp employee ID. The contact, inquiry and job search tools, and |
Use a dedicated MarketSharp employee set up for API access rather than a person's login. The server never uses MarketSharp usernames or passwords.
Related MCP server: EODHD MCP Server
Tools (25, all read-only)
Tool | MarketSharp endpoint |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
There are no create, update or delete tools. Searches and filtered lists use
POST because that is how MarketSharp exposes them; they don't change data.
The client only sends the GET and POST routes these tools use (an allowlist of
route templates in src/client.ts). Any other request, including a GET no
tool uses, is refused before sign-in.
Running
Requires Node.js 22 or later.
npm ci && npm run build
MARKETSHARP_COMPANY_ID=… MARKETSHARP_API_KEY=… MARKETSHARP_API_SECRET=… node dist/index.js # stdioThe Docker image defaults to MCP_TRANSPORT=http and AUTH_MODE=gateway.
To run the image over stdio with MARKETSHARP_* credentials, pass
-e MCP_TRANSPORT=stdio -e AUTH_MODE=env as well; otherwise it fails closed
with "credentials are not configured".
HTTP (MCP_TRANSPORT=http, /mcp + /health) refuses to start without a real
CONDUIT_S2S_SECRET (at least 32 characters, not a known or placeholder-looking
value, not a repeated pattern, at least 8 distinct characters) and requires a
valid X-Gateway-S2S header on every /mcp request. /mcp takes POST only
(405 with Allow: POST otherwise). MCP_ALLOWED_HOSTS (comma-separated, off
when unset) limits the Host headers /mcp accepts. Every response sets
Cache-Control: no-store.
AUTH_MODEisgateway(the default when unset) orenv. Any other value refuses to start. Ingatewaymode credentials come only from thex-marketsharp-*headers;MARKETSHARP_*env is never read.envis for a single tenant and readsMARKETSHARP_*from the environment; over HTTP it refuses to start unless the company id, API key and API secret are set and the ids look like MarketSharp ids. Stdio uses the environment only whenAUTH_MODEis unset or exactlyenv; any other value (including a typo) is treated asgateway, so env credentials are never used by mistake.Tool tiers:
readis the only tier. Conduit'sX-Conduit-Tool-Tiersheader can only narrow that set for one request. A present but empty header means no tools at all. Unlike the fleet template there is deliberately noMARKETSHARP_TOOL_TIERSvariable: with one tier there is nothing to choose, and nothing in the environment can change the tier set.Every request goes to the fixed host
https://restapi.marketsharpm.comat exactly the path that was built. Ids in paths must look like MarketSharp ids (1-64 letters, digits or dashes, which covers numbers and GUIDs); anything else is rejected before any request. Redirects are refused (redirect: 'manual', any 3xx is an error), so the bearer token never leaves the host. Response bodies are read with a 4 MiB cap.Tool output, tool errors and log lines are redacted: the API key and secret in use (env or per request), bearer tokens and JWTs become
[REDACTED]. In MarketSharp responses, values under credential-named keys (apiKey,authorization,token,accessToken,refreshToken, and any key ending inpasswordorsecret) are redacted too. Arguments a tool doesn't declare are dropped before it runs. Vendor errors keep the HTTP status, MarketSharp's message and, when sent, the request id (x-request-id,request-idorx-correlation-id).Page sizes and record counts above a tool's maximum are rejected, not silently lowered, so "fewer rows than
rowsPerPagemeans the last page" stays true. Pages are passed through as given; the server never fetches more than one page per call.MCP_ALLOW_INSECURE_DEV=1lets HTTP start without a secret, on 127.0.0.1 only, and requiresNODE_ENV=development. With any otherNODE_ENVthe server refuses to start.Tool output is MarketSharp data that other people may have typed (lead forms, notes, names). Every successful result is escaped and wrapped in
<untrusted-content nonce="…">markers behind a notice telling the model not to follow instructions inside it. MarketSharp's own error text is wrapped the same way.
See .env.example. The image's health check probes /health only when
MCP_TRANSPORT=http.
Limits and unknowns
MarketSharp doesn't publish rate limits. The server retries 429 with
Retry-Afteror exponential backoff (3 tries). A 503 is retried only for GET requests. Searches and filtered lists (which use POST) return it instead.The
/token200 response shape isn't documented. The server acceptsaccess_tokenortoken, top level or insideresponse, or a bare JWT body (plain or JSON-quoted).HTTP request bodies are capped at 256 KiB (262,144 bytes). Larger bodies, declared or chunked, get a 413.
Responses are capped at 200,000 characters; narrow with filters or paging. An oversized list keeps whole records and its paging fields (also when the page sits under
responseordata), and a note says how many records were left out. On the paged lists the note names the exactpageNumberandrowsPerPage(pageandpageSizefor employees) that read on from the first record left out; other tools can't page, so it says to narrow with filters. A list whose first record alone is over the cap is cut as text.The QuickFind searches always send
numberOfRecords(default 25): it is a non-nullable int32 in the spec, and what MarketSharp does with 0 is undocumented.Not covered: calendar, texting, email, PaySimple, QuickBooks, CompanyCam, automation rules, analytics, estimates (v1 only), and all admin/config writes.
Security notes
companyIdandemployeeIdare identifiers, not secrets. The companies tools return them by design.MCP_ALLOWED_HOSTSis opt-in defence in depth behind S2S, not an auth control. It matches the Host header's hostname and ignores the port.The S2S signature covers only the timestamp, the same as the gateway's verifier. Recipient binding comes from the per-vendor subkey.
MCP_ALLOW_INSECURE_DEVmust never be set in a deployment.A request has at most 4 MarketSharp calls in flight, each counted from the start of the fetch until its response body is fully read. A large JSON-RPC batch queues instead of fanning out. A retry's wait doesn't hold a slot.
Development
npm ci --ignore-scripts
npm run typecheck # tsc --noEmit
npm run lint # eslint + destructive-tool warning lint
npm run lint:destructive # destructive-tool warning lint only
npm run build
npm test # vitest, no network
npm run smoke # spawns dist/index.js over stdio, no networkevals/ holds the mcp-assert suite that CI runs against the built server.
Each release publishes ghcr.io/wyre-ai/marketsharp-mcp, and its release notes are on the GitHub Release for that version.
License
Apache-2.0
Available Tools
25 toolsmarketsharp_activity_types_listARead-onlyIdempotent
List the company's activity types (e.g. Call, Email, Follow Up).
Inputs: includeInactive.
marketsharp_appointment_results_listARead-onlyIdempotent
List the company's active appointment results (e.g. Sold, No Sale), or the result reasons.
Inputs: reasons.
marketsharp_appointments_getARead-onlyIdempotent
Get one appointment by ID: time, salespeople, type, result and address.
Inputs: appointmentId (required).
marketsharp_appointments_listARead-onlyIdempotent
List appointments page by page by appointment date range, change date range, salesperson or inquiry. Use this for "what's on the schedule".
Inputs: inquiryIds, modifiedTo, pageNumber, rowsPerPage, +4 more.
marketsharp_appointments_list_by_contactBRead-onlyIdempotent
List every appointment for one contact.
Inputs: contactId (required).
marketsharp_companies_getARead-onlyIdempotent
Get this connection's MarketSharp company profile (name, address, time zone and settings).
Inputs: no named parameters.
marketsharp_companies_listARead-onlyIdempotent
List the MarketSharp companies this API key can access, with their IDs.
Inputs: no named parameters.
marketsharp_contacts_getARead-onlyIdempotent
Get one contact (customer or prospect) by contact ID: name, addresses, emails, phone numbers and do-not-contact flags.
Inputs: contactId (required).
marketsharp_contacts_listBRead-onlyIdempotent
List contacts page by page, optionally only those changed since a date or with appointments in a date range or for one salesperson.
Inputs: pageNumber, rowsPerPage, appointmentTo, modifiedSince, +2 more.
marketsharp_contacts_searchARead-onlyIdempotent
Find contacts by name, business, email, phone or address (MarketSharp QuickFind). Needs an Employee ID on the connection, and runs with that employee's MarketSharp permissions.
Inputs: zip, city, state, last_name, +6 more.
marketsharp_divisions_listCRead-onlyIdempotent
List the company's divisions.
Inputs: no named parameters.
marketsharp_employees_listBRead-onlyIdempotent
List employees (salespeople, project managers and staff) with their IDs, page by page.
Inputs: page, search, pageSize, activeOnly.
marketsharp_inquiries_getARead-onlyIdempotent
Get one inquiry (lead) by ID: date, status, lead sources, product interests, address and notes.
Inputs: inquiryId (required), appointmentRequired.
marketsharp_inquiries_listBRead-onlyIdempotent
List inquiries (leads) page by page, optionally only those changed in a date range, with appointments in a date range, or for one salesperson.
Inputs: modifiedTo, pageNumber, rowsPerPage, modifiedFrom, +4 more.
marketsharp_inquiries_list_by_contactBRead-onlyIdempotent
List every inquiry (lead) for one contact.
Inputs: contactId (required), appointmentRequired.
marketsharp_inquiries_searchARead-onlyIdempotent
Find inquiries (leads) by the contact's name, business, email, phone or the inquiry address (QuickFind). Needs an Employee ID on the connection, and runs with that employee's MarketSharp permissions.
Inputs: zip, city, state, last_name, +6 more.
marketsharp_inquiry_notes_listARead-onlyIdempotent
List the notes on an inquiry (lead), or on the job created from it. Needs MarketSharp's View Opportunity Note permission.
Inputs: inquiryId (required), noteType.
marketsharp_inquiry_statuses_listCRead-onlyIdempotent
List the company's inquiry (lead) statuses.
Inputs: includeInactive.
marketsharp_jobs_getARead-onlyIdempotent
Get one job by ID: name, type, status, site address, sale and completion dates, and contract total.
Inputs: jobId (required).
marketsharp_jobs_searchARead-onlyIdempotent
Find jobs by job name or number, or by the contact's name, business, email, phone or address (QuickFind). Needs an Employee ID on the connection, and runs with that employee's MarketSharp permissions.
Inputs: zip, city, state, job_name, +8 more.
marketsharp_lead_sources_listARead-onlyIdempotent
List the company's primary lead sources, or the secondary lead sources under one primary source.
Inputs: includeInactive, primaryLeadSourceId.
marketsharp_notes_listARead-onlyIdempotent
List the notes for a contact: all types, or one type such as ContactNote, Appointment, Inquiry or Job. Needs an Employee ID on the connection, and runs with that employee's MarketSharp permissions.
Inputs: contactId (required), noteType.
marketsharp_opportunities_listARead-onlyIdempotent
List opportunities (jobs and leads) changed since a date, with job numbers, sale and contract dates, contract totals, contract status and balance due. Returns at most numberOfRecords (max 1000) with no paging. If you get exactly that many, the list may be incomplete: raise numberOfRecords (up to 1000), and say the result may be incomplete if it is already 1000. Needs MarketSharp's View Opportunity permission.
Inputs: fromDate (required), numberOfRecords.
marketsharp_product_interests_listARead-onlyIdempotent
List the company's product interests (e.g. Windows, Siding), or the ones attached to one inquiry (lead). Needs MarketSharp's View Product Interest permission.
Inputs: inquiryId, includeInactive.
marketsharp_search_globalARead-onlyIdempotent
Search the company for contacts, inquiries (leads) and jobs by name, address, email, phone or job number. Start here when you only have a name or phone number.
Inputs: query (required), type, numberOfRecords.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 25 tools
Most tools map to a distinct resource+action (contacts_get vs contacts_list vs appointments_list_by_contact), and the by_contact variants are clearly separated from the paged listers. The main overlap is the search family: search_global, contacts_search, inquiries_search and jobs_search all do QuickFind-style lookups, though descriptions do steer agents to start with search_global and note the Employee ID requirement on the others. notes_list vs inquiry_notes_list is also a subtle boundary but is explained.
Nearly everything follows marketsharp_<resource>_<verb> with a shared prefix, which is highly predictable. Minor deviations: search_global is verb-first rather than resource-first, and some resources are singular where others are plural (inquiry_statuses_list, inquiry_notes_list, appointment_results_list vs contacts_list). notes_list is also vaguer than the pattern implies (it is contact-scoped notes).
At 25 tools this is at the upper bound, but the domain is broad (contacts, inquiries, appointments, jobs, opportunities, notes) and seven of the tools are small reference-data lookups (statuses, results, activity types, lead sources, product interests, divisions, employees) that genuinely earn their place. It is heavy but not padded.
The read surface is thorough across every major entity, but the server appears read-only: there is no create, update or delete for contacts, inquiries, appointments, jobs or notes, which is a notable gap for a CRM. Job enumeration is also awkward — there is jobs_get and jobs_search but no jobs_list, so listing jobs depends on opportunities_list, which is change-date driven and capped at 1000 records with no paging.
Maintenance
Related MCP Connectors
Unofficial remote MCP server for Less Annoying CRM: OAuth 2.1, read-only grants, 10 tools.
Read-only access to InfluSense influencer discovery, ratings, watchlists, and reports via MCP.
Native MCP access to CRM contacts, organizations, deals and tasks with user permissions.
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Related MCP Servers
- AlicenseAqualityDmaintenanceRead-only MCP server for the Daktela contact center REST API, providing 40 tools to access tickets, calls, emails, chats, contacts, CRM records, campaigns, and real-time agent status.451MIT
- AlicenseNot gradedqualityDmaintenanceEnables access to financial market data including EOD, intraday, fundamentals, news, and more via 75 read-only MCP tools.5MIT
- FlicenseAqualityCmaintenanceExposes read-only GoCanvas API v3 endpoints as MCP tools, enabling listing and retrieval of forms, submissions, reports, and reference data.16-
- AlicenseAqualityDmaintenanceProvides read-only access to the Mailchimp Marketing API v3 via 18 tools covering 103 endpoints for audiences, members, campaigns, reports, automations, templates, landing pages, e-commerce, and account administration.1899 npmMIT