MCP server
Meshie's checks as tools any agent that speaks MCP can call before and after a change to your GTM stack. Add Meshie to Claude, Claude Code or Cursor and sign in to a workspace, or run the same server locally against a snapshot on disk.
Connect from Claude
The hosted server is https://meshie.ai/api/mcp. Every plan can connect, within the workspace’s monthly questions and proposals. You sign in with your Meshie account, choose one workspace, and approve what the connection may do; there is no key to paste and no header to set. The URL has no slug because the connection names the workspace you chose. Settings, Claude in the app shows these steps with a copy button and lists your connections.
claude.ai and Claude Desktop
- In Claude, open Settings, then Connectors, and choose Add custom connector.
- Name it Meshie and paste
https://meshie.ai/api/mcp. - Leave Sign in now and Use Claude’s published identity selected. No client ID, secret or headers are needed.
- Click Connect. Sign in to Meshie, choose the workspace, and click Connect again to approve.
Claude Code
claude mcp add --transport http meshie https://meshie.ai/api/mcpClaude Code opens your browser to sign in and hands the result back to a program on your computer, so the approval page warns you about that. Only approve a request you just started.
Cursor
{
"mcpServers": {
"meshie": {
"url": "https://meshie.ai/api/mcp"
}
}
}Cursor opens your browser to sign in the first time it connects. If sign-in fails, for example on an older Cursor that returns to a cursor:// address Meshie does not accept, use a CLI token instead.
Try it on the demo workspace
No system connected yet? On the workspace’s Overview, choose Explore a demo org. It loads a synthetic stack (Salesforce, HubSpot, Fivetran Activations (formerly Census) and Hightouch) that every tool works against. Then ask:
- “What breaks if we rename the SaaS - Enterprise value of the Industry picklist?” Claude can find the value with
meshie_search_componentsand then callmeshie_get_impactonsalesforce:PicklistValue:StandardValueSet.Industry:SaaS - Enterprise. The answer reaches past Salesforce (a lead routing flow, a validation rule, a workflow rule) into a HubSpot workflow, a Fivetran Activations sync and a Hightouch sync. - “Which custom fields on Account have no references, and can we delete them?”
meshie_list_unusedwithobjectset toAccountreturnsAccount.Ghost_Ref__c, led by why unused never means safe to delete. - “What reads Account.Account_Status__c, and which flows depend on it?”
meshie_get_impactonsalesforce:CustomField:Account.Account_Status__clists Apex, an email template, page layouts and several flows, each with its tier and evidence.
Tools
| Tool | What it answers |
|---|---|
Toolmeshie_search_components | What it answersFind a node id by substring. The entry point; every other tool takes an id. |
Toolmeshie_get_impact | What it answersWhat breaks if this node changes: reachable_from_unknown first, then every reference with tier, confidence and evidence, then affected nodes by system. |
Toolmeshie_list_unused | What it answersFields with no inbound reference, led by what unused does not mean. |
Toolmeshie_list_systems | What it answersDetected vendors, which are connected, and the coverage note. |
Toolmeshie_browse_system | What it answersOne hub's components grouped by type, before you know what to search for. |
Toolmeshie_ask | What it answersA grounded prose answer. Optional: your AI can answer with the read tools directly, while Ask runs Meshie's own model on every call and returns text. |
Toolmeshie_propose_change | What it answersCheck a Salesforce metadata change your AI has worked out: it sends change_class, operation, object, field and the values the operation needs, and Meshie checks it with no model call of its own, refusing when the class it re-derives from the fields differs. Plain English in request is the fallback and costs a model call. Returns the change it checked, the diff, the blast radius across every connected hub and a verdict. Hosted, files the proposal in the workspace's change ledger and returns run_id. Needs the propose scope. |
Toolmeshie_record_outcome | What it answersReport that a proposed change (its run_id) has shipped through your own pipeline, optionally naming the scan delta that shows it. The next scan of that hub grades what actually changed against the proposal and closes the run with a verdict and an escaped-defect flag. Hosted only. Needs the record scope and the ADMIN role. |
Every list tool takes limit and offset and returns total, count, has_more and next_offset around its items. Every tool takes response_format, json by default or markdown. Tier and confidence survive both.
What a result looks like in a chat client
- Every JSON result ends with a
summaryMeshie writes from counts and verdicts,linksinto the web app (hosted only: the impact page formeshie_get_impact, the change page for a proposal), and adata_notice. Impact references and unused fields carry their ownimpact_url. - Names, labels, picklist values and other text from your own systems are data, not instructions. The markdown form puts them between
<customer_metadata>tags, and the summary never quotes them. evidence_fileis relative to the system’s metadata root, for exampleobjects/Opportunity/fields/Stage__c.field-meta.xml. No result carries a server path or an internal workspace, user or snapshot id.- Output is bounded:
depthis capped at 6, a page holds at most 100 items, any list that is not paginated is capped at 25 entries with the full count and a link to the rest, and one result stays under 30,000 characters. When long names would push a result over, you get a shorter page or list that says where the rest is, never a result cut off part way. - Errors say what to do next: no scan yet (connect a system or load the demo), a missing scope, a system that is not connected, or a monthly quota that resets on the 1st.
Advanced: CLI tokens
For scripts, CI, and clients that cannot sign in: the same hosted server, authenticated with a pasted bearer token instead. CLI tokens are a Pro feature. Create one in Settings, CLI tokens, tick the propose scope if the agent should be able to propose, and send it as a bearer token. The token names the workspace, so the URL has no slug.
Claude Code with a token
claude mcp add --transport http meshie https://meshie.ai/api/mcp \
--header "Authorization: Bearer agtm_..."Cursor with a token
{
"mcpServers": {
"meshie": {
"url": "https://meshie.ai/api/mcp",
"headers": { "Authorization": "Bearer agtm_..." }
}
}
}Any client, or curl
The endpoint is streamable HTTP in stateless JSON mode: one POST per JSON-RPC message, one JSON reply, no session to hold and no event stream to read. A signed-in GET returns 405 with Allow: POST, the protocol’s way of saying there is no event stream.
curl -s https://meshie.ai/api/mcp \
-H "Authorization: Bearer agtm_..." \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"meshie_get_impact","arguments":{"node_id":"salesforce:CustomField:Account.Status__c"}}}'Local: your own snapshot
No account and no network. Scan a metadata export, then point your client at meshie mcp.
uv tool install "meshie[mcp] @ git+https://github.com/cr-digital-services/meshie.git"
meshie scan --source ./force-app/main/defaultClaude Code, local
claude mcp add meshie -- meshie mcpOr in .mcp.json at the repository root, which checks in with the project:
{
"mcpServers": {
"meshie": {
"command": "meshie",
"args": ["mcp", "--snapshot", ".meshie/snapshot.json"]
}
}
}Cursor, local
{
"mcpServers": {
"meshie": {
"command": "meshie",
"args": ["mcp", "--snapshot", ".meshie/snapshot.json"]
}
}
}meshie_ask needs ANTHROPIC_API_KEY in the server’s environment; the other tools need nothing. A rescan is picked up on the next call.
Scopes
A Claude connection gets the scopes you approve on Meshie’s consent page; a CLI token gets the ones ticked when it was created.
readis on every connection and every token and covers all six read tools.proposeunlocksmeshie_propose_changeandPOST /api/w/{slug}/changes/propose. Claude asks for it, and the consent page shows it as Draft checked changes, ticked by default; untick it for a read-only connection.recordunlocksmeshie_record_outcomeandPOST /api/w/{slug}/changes/{run_id}/outcome. Claude asks for it, and the consent page shows it as Record outcomes of shipped changes, ticked by default for a workspace admin or owner. A member without the ADMIN role is not granted it and does not seemeshie_record_outcome, since recording an outcome is what makes the next scan grade a change. Connections made before Claude asked for it holdreadandproposeonly; reconnect to add it.scanunlocks starting a retrieve. CLI tokens only.
Each connection or token reaches one workspace, at its member’s own role. The tool list shows only the tools that connection or token can call, by its scopes and the member’s current role. A tool called without its scope returns a tool error naming the scope. Tokens created before scopes existed have read only. Revoke a Claude connection in Settings, Claude, and a token in Settings, CLI tokens; revocation takes effect on the next request.
Reading a proposal
meshie_propose_change first states checked_change, the change Meshie read from your AI’s structured request in one sentence, so a misread shows before anything else. Then the two things an agent is most likely to skip: unknown_edges_reached and unmonitored_hubs. Then the verdict and its reason, then the full report: the classification record (the class your AI stated against the class Meshie re-derives from the fields, or for plain English two classifiers; the run refuses when they disagree), the proposed diff or the refusal, the blast radius with tier, confidence and evidence per hop, and the checks that could not run. writes_to_org is always false and the report fails validation if it is not. See the impact query and unknown edges for how to read the rest.
Closing the loop
A hosted proposal is a row in the workspace’s change ledger (the Changes page in the app), and run_id names it. Once the change has gone out through your own pipeline, call meshie_record_outcome with that id. The next scheduled scan of the hub diffs what changed, scopes it to the neighbourhood of the proposal’s targets, grades the proposal against it with the same grader the benchmark uses, and closes the run with a verdict, an escaped-defect flag and the dependencies the impact result missed. Anything else that changed in the same scan is recorded as concurrent drift and never counts against the proposal. If the scan already ran before you recorded the outcome, the run is graded against it immediately; pass delta_id to name a specific scan.