Synqed Enterprise MCP Gateway Documentation Audit
A gateway that markets "zero integration friction" ships docs where the same tool carries three different names, the Quickstart's headline example tool isn't in the catalog, the API guide's auth-config example fails validation against the published enum and sends a field the OpenAPI schema doesn't define — and the one auth-config example the docs lean on is a HubSpot/GitHub copy-paste mashup. These are exactly the silent failures AI agents can't recover from.
1. The same tool is named three incompatible ways, and the Quickstart's example tool isn't in the catalog (critical)
Location: /platform-docs/quickstart, /mcp-servers/hubspot, /platform-docs/dedicated-gateway, /platform-docs/logs, /api-reference/gateways/create-a-gateway
Problem: HubSpot tools appear under three different conventions across the docs. The authoritative HubSpot server page (/mcp-servers/hubspot) defines the catalog as 229 tools prefixed HSPOT_* (e.g. HSPOT_READ_CONTACT, HSPOT_GET_CONTACT_BY_EMAIL). But the Dedicated Gateway page tells you to enable HUBSPOT_CREATE_CONTACT and HUBSPOT_UPDATE_DEAL, the Logs page shows HUBSPOT_LIST_CONTACTS, and the create-a-gateway API reference example uses lowercase create_contact. Worse, the Quickstart's headline example — "HubSpot exposes tools like HSPOT_CREATE_CONTACT and HSPOT_GET_CONTACT" — names two tools that do not appear in the documented HSPOT_* catalog: the sample identifiers shown on the server page include HSPOT_READ_CONTACT and HSPOT_GET_CONTACT_BY_EMAIL, but no bare HSPOT_CREATE_CONTACT/HSPOT_GET_CONTACT.
Consequence: A developer or AI agent that copies a tool name from the Quickstart, the Dedicated Gateway page, or the Logs UI will call a tool identifier that doesn't match the catalog. For agents this fails silently — the tools/call either errors or routes nowhere, and there is no page reconciling which prefix is real. The one page a user is most likely to read first (Quickstart) shows names that don't appear in the catalog it points to.
The fix: Pick one canonical tool-naming scheme (HSPOT_* per the server page) and propagate it to the Quickstart, Dedicated Gateway, Logs, and all API examples. Replace the unfindable HSPOT_CREATE_CONTACT/HSPOT_GET_CONTACT in the Quickstart with real catalog identifiers.
2. auth_method_type enum mismatch — the API guide's value fails validation (critical)
Location: /platform-docs/api-usage-guide, /api-reference/auth-configs/create-auth-config
Problem: The API usage guide's create-auth-config example sends "auth_method_type": "oauth2". The create-auth-config API reference states the enum is Available options: oauth, api_key — oauth2 is not a valid value.
Consequence: A developer copy-pasting the API guide's request body gets a validation_failed error on their first real call. An agent generating requests from the guide will do the same with no hint that the correct token is oauth.
The fix: Standardize on the enum the API actually accepts (oauth) and correct the API usage guide example. Verify every auth_method_type occurrence in prose and code samples.
3. Create-auth-config sends is_default, a request property that doesn't exist — and the page contradicts itself about it (critical)
Location: /platform-docs/api-usage-guide, /api-reference/auth-configs/create-auth-config, /api-reference/openapi.json
Problem: Three sources disagree. (a) The API usage guide's create-auth-config request body includes "is_default": true. (b) The OpenAPI spec's dto.CreateAuthConfigRequest schema has no is_default field — its only properties are auth_method_type, name, oauth_override, scopes, server_slug. (c) The create-auth-config reference page's own description states "Auth configs created via this API always have is_default=false," yet its response example returns "is_default": true.
Consequence: The guide instructs developers to send a property the API ignores or rejects, while simultaneously promising the field can never be true via the API — then shows it as true in the response. A developer relying on is_default to mark a production auth config the default will silently get the opposite behavior, with no documented way to set it.
The fix: Remove is_default from the API guide's request body. Make the create-auth-config response example consistent with the stated invariant (is_default=false). If a default can be set, document the actual endpoint that does it.
4. dynamic exposure mode is defined two contradictory ways (critical)
Location: /platform-docs/api-usage-guide, /api-reference/gateways/create-a-gateway
Problem: The API usage guide defines the two modes as: "dynamic: serve all tools from connected servers, optionally filtered by annotation hints" and "custom: serve a curated tool list from explicit servers." But the create-a-gateway reference's canonical "exposure_mode": "dynamic" example pairs dynamic with "include_all_servers": false, an explicit single-server servers array, and an explicit tools array containing one curated tool — i.e. it behaves exactly like the guide's definition of custom.
Consequence: Developers and agents cannot predict what a dynamic gateway will actually expose. Does dynamic serve all tools, or only the curated tools list shown in the reference? The two pages give opposite answers, and exposure_mode is documented as immutable (per llms.txt: "Exposure mode is immutable") — so a wrong choice can't be corrected without rebuilding the gateway.
The fix: Define precisely how exposure_mode, include_all_servers, servers, and tools interact in each mode, and make the create-a-gateway example match the definition. If tools/include_all_servers are ignored in dynamic mode, say so explicitly.
5. The create-auth-config example is a HubSpot/GitHub copy-paste mashup (significant)
Location: /api-reference/auth-configs/create-auth-config
Problem: The "HubSpot OAuth - Production" example — "name": "HubSpot OAuth - Production", "server_slug": "hubspot", response scope crm.objects.contacts.read — sends GitHub credentials and GitHub scopes in its request body: "client_id": "github-client-id", "client_secret": "github-client-secret", "scopes": ["repo", "read:user"]. The request and response describe two different products. This is the exact example findings #2 and #3 already dissect for other defects.
Consequence: A developer setting up HubSpot auth and copying the canonical example provisions GitHub OAuth scopes (repo, read:user) against a HubSpot server slug — credentials and scopes that don't apply to HubSpot at all. The request will either fail or create a misconfigured auth config, and an agent generating HubSpot setup from this template inherits the wrong scopes silently.
The fix: Make the example internally consistent — a HubSpot example should carry HubSpot scopes (e.g. crm.objects.contacts.read) and clearly-placeholdered HubSpot credentials. Audit every reference example for cross-provider value bleed.
6. Server slugs are UPPERCASE on every server page but the API requires lowercase (significant)
Location: /mcp-servers/hubspot, /mcp-servers/github, /mcp-servers/airtable, /platform-docs/api-usage-guide, /api-reference/*
Problem: Every server reference page presents the slug in uppercase — Server slug | HUBSPOT, GITHUB, AIRTABLE — while every API example and response uses lowercase ("server_slug": "hubspot", "slug": "github", list-mcp-servers returns "slug": "hubspot").
Consequence: A developer who reads the server page for the slug and passes HUBSPOT to POST /auth-configs or /connections risks a not_found/validation_failed error if the API is case-sensitive (which the lowercase-only API responses imply). Agents extracting the slug from the human-readable server page will get it wrong.
The fix: Show slugs in the exact case the API accepts (lowercase) on the server pages, or explicitly state slugs are case-insensitive. Don't display an identifier in a casing the API never returns.
7. GitHub custom-gateway example uses tool names that don't exist in the catalog (significant)
Location: /platform-docs/api-usage-guide, /mcp-servers/github
Problem: The API guide's custom-gateway example lists { "server_slug": "github", "tool_name": "create_issue" } and "list_repos". The GitHub server page documents 30 tools prefixed GITHUB_*: GITHUB_CREATE_ISSUE exists (different casing/prefix), but there is no list_repos — the closest catalog entries are GITHUB_LIST_ORG_REPOS and GITHUB_SEARCH_REPOSITORIES.
Consequence: Building a custom gateway from the API guide's example produces a gateway referencing a non-existent tool (list_repos) and a mis-cased one (create_issue). Custom gateways validate against explicit tool lists, so this is a likely hard failure at creation or call time.
The fix: Replace the example tool names with real catalog identifiers (GITHUB_CREATE_ISSUE, GITHUB_LIST_ORG_REPOS) and reconcile prefix/casing with the server page.
8. HubSpot tool count disagrees by ~10x between the API and the server page (significant)
Location: /api-reference/mcp-servers/list-mcp-servers, /mcp-servers/hubspot
Problem: The list-mcp-servers API response example reports "total_tools": 24 for HubSpot. The authoritative HubSpot server page states the catalog is 229 tools (HSPOT_*). That is a roughly 10x disagreement on the same server's tool count between the API list response and the human-facing catalog page.
Consequence: An agent enumerating HubSpot's capabilities programmatically via list-mcp-servers sees 24 tools and concludes 205 documented tools don't exist; a human reading the server page expects 229 and can't reconcile why the API reports a fraction. Either the example is fabricated or the API and docs are counting different things — and nothing on either page explains which.
The fix: Regenerate the list-mcp-servers example from a real response, and reconcile total_tools with the server page's catalog count (or document explicitly why the two numbers differ — e.g. enabled vs. total).
9. No endpoint documents error responses, despite a published error-code list (significant)
Location: /api-reference/* (all endpoint pages), /platform-docs/api-usage-guide
Problem: The API usage guide lists nine error codes (validation_failed, bad_request, unauthorized, forbidden, quota_exceeded, not_found, conflict, rate_limited, internal_error), but every endpoint page in the API reference documents only the success case — e.g. get-mcp-connection-url shows just "Response — OK". No endpoint page documents which status codes it can return, the error body shape, or which of the nine codes applies where.
Consequence: Developers can't write error handling without trial and error, and agents have no way to map a failure to a recoverable action (retry on rate_limited, re-auth on unauthorized, etc.). The error codes are a flat list with no contract tying them to endpoints.
The fix: Document the error response body schema once, and list the possible error codes/status codes per endpoint (or at minimum per resource group).
10. Two overlapping connection-creation endpoints with no guidance on which to use (significant)
Location: /api-reference/connections/initiate-connection, /api-reference/sessions/create-or-get-session, /platform-docs/api-usage-guide
Problem: Connections can apparently be created two ways: a top-level POST /v1/connections (initiate-connection), and an instance-scoped POST /v1/gateways/{gateway_id}/instances/{instance_id}/connections (used by the API guide and create-connection-link flow). The docs never explain when to use which, or how a top-level connection relates to an instance.
Consequence: Developers must guess which path fits their flow, and agents have no rule for choosing. Picking the wrong one may create orphaned connections or connections not bound to the gateway instance the agent actually uses.
The fix: Document both endpoints side by side with a clear "use this when…" decision, and explain how a top-level connection associates with gateways/instances.
11. Session example shows a connected connection that still carries a redirect_url (significant)
Location: /api-reference/sessions/create-or-get-session, /platform-docs/api-usage-guide
Problem: The API guide states the OAuth pattern: "If a server returns redirect_url, send the user through that OAuth flow" — i.e. redirect_url signals a not_connected server. But the create-or-get-session response example shows a connection with "connection_status": "connected" that nonetheless includes a populated redirect_url.
Consequence: Code (or an agent) that treats "has redirect_url" as "needs OAuth" will loop an already-connected user back through authorization. The signal the docs tell you to branch on is shown firing on a state where it shouldn't.
The fix: Either omit redirect_url for connected connections in the example, or document precisely when redirect_url is present regardless of status and what consumers should key off instead (e.g. connection_status).
12. Gateway UI types (Dedicated / ToolRouter) are never mapped to the API's exposure_mode values (significant)
Location: /platform-docs/how-synqed-MCP-gateway-works, /platform-docs/dedicated-gateway, /platform-docs/toolrouter-gateway, /api-reference/gateways/create-a-gateway
Problem: The platform docs describe two gateway types by name — "Dedicated Gateway" (manually select servers/tools) and "ToolRouter Gateway" (runtime discovery via ten meta-tools). The API exposes exposure_mode with values dynamic/custom. No page states which UI type corresponds to which exposure_mode value.
Consequence: A developer who configured a "Dedicated" gateway in the UI and now wants to script it has to guess whether that maps to custom or dynamic (and given finding #4, even the API-side definitions conflict). This blocks anyone moving from console to API.
The fix: Add an explicit mapping table: Dedicated ↔ custom, ToolRouter ↔ dynamic (or whatever is correct), and use consistent vocabulary across UI and API docs.
13. Rate limiting is described three different ways (significant)
Location: /platform-docs/quickstart, /platform-docs/dedicated-gateway, /platform-docs/toolrouter-gateway, /platform-docs/api-usage-guide
Problem: The gateway rate-limit setting is "Maximum requests per time window" (Quickstart), "Maximum number of requests allowed per second" (Dedicated and ToolRouter), while the API-level limit is a concrete "300 requests/minute" shared across all API keys (API guide). The per-gateway control's unit is stated inconsistently and never given a concrete default or range.
Consequence: A developer configuring rate limiting can't tell whether the number they enter is per second or per some unspecified window — a 60x difference. Capacity planning and load tests will be wrong.
The fix: State the exact unit for the gateway rate-limit field consistently on every page, and separate it clearly from the global 300 req/min API key limit.
14. Client Authentication options differ between pages (significant)
Location: /platform-docs/quickstart, /platform-docs/how-synqed-MCP-gateway-works, /platform-docs/dedicated-gateway
Problem: The Quickstart and How-it-works pages list three client-auth options — API Key, No Auth, Basic Auth. The Dedicated Gateway page lists only "No Auth and API Key," omitting Basic Auth entirely.
Consequence: A developer following the Dedicated Gateway flow won't know Basic Auth is available; one relying on Basic Auth can't tell whether it's supported for dedicated gateways or only elsewhere.
The fix: List the same client-authentication options on every gateway-configuration page, or explicitly note where Basic Auth is unavailable and why.
15. ToolRouter ships remote code-execution meta-tools with no documented security model (significant)
Location: /platform-docs/how-synqed-MCP-gateway-works, /platform-docs/toolrouter-gateway
Problem: The ToolRouter's ten meta-tools include RUN_SANDBOX_PYTHON ("Execute Python code in a persistent remote sandbox") and RUN_SANDBOX_BASH ("Execute a bash command in the persistent remote sandbox"), with a /workspace preserved across calls. The docs describe what these tools do but document none of their security model: tenant isolation of the sandbox, network egress, what credentials/connections the sandbox process can reach, or how to disable code execution. The ToolRouter's tool-safety toggles (Read Only / Destructive / Idempotent / Open World) are documented, but the docs never state which category gates arbitrary code execution or whether these meta-tools are subject to those toggles at all.
Consequence: A security-conscious team evaluating Synqed cannot answer basic questions before granting an agent these tools — is the sandbox isolated per organisation, can executed code reach connected upstream credentials, and how do you turn it off? Shipping arbitrary-code-execution capability without a documented isolation/authorization model is a blocker for enterprise approval and an unbounded risk for anyone who enables it by default.
The fix: Add a security section for the sandbox meta-tools covering isolation boundary, network/credential access, default on/off state, and exactly which safety toggle (if any) controls them — and how to disable code execution entirely.
16. llms.txt — the agent index — links to a different company's blog (significant)
Location: /llms.txt
Problem: The llms.txt "Optional" section's Blog link points to https://softphone.ai/blog/, a different domain entirely, not synqed.ai. llms.txt is the file AI agents use to index the docs.
Consequence: An agent crawling Synqed's llms.txt to build context will fetch and ingest an unrelated domain's blog as if it were Synqed content — polluting retrieval with off-brand material. For a product whose whole pitch is reliable agent tooling, the agent-facing index leaks to a third party.
The fix: Point the Blog link to Synqed's own blog (or remove it). Audit every URL in llms.txt to confirm it stays on synqed.ai/docs.synqed.ai.
17. Broken pagination example: prev_page: 123 while on page 1 of 5 (minor)
Location: /api-reference/mcp-servers/list-mcp-servers
Problem: The list-mcp-servers response example shows "current_page": 1, "total_pages": 5, "next_page": 2, but "prev_page": 123 — an impossible value (there is no previous page from page 1, and 123 exceeds total_pages).
Consequence: A developer modeling pagination off this example may write logic that trusts prev_page, or waste time trying to reconcile the nonsensical value. It also undermines confidence that the examples reflect real responses.
The fix: Regenerate the example from a real response so prev_page is null (or absent) on page 1.
18. API version is labeled inconsistently and there is no changelog despite "Experimental" status (minor)
Location: /api-reference/openapi.json, /platform-docs/api-usage-guide, /llms.txt
Problem: The OpenAPI spec reports info.version: "1.0", the API guide refers to the API as v1 and labels it "Experimental," and no changelog or versioning page is listed anywhere in the docs index (including llms.txt).
Consequence: Developers can't tell what "Experimental" guarantees about stability, can't track breaking changes, and have no migration signal — risky for an API that explicitly warns it may change. The version string (1.0) even reads as stable, contradicting the "Experimental" label.
The fix: Reconcile the version label, define what "Experimental" means for stability, and publish a changelog page listing breaking changes.
19. Response includes both gateway_status and status for the same gateway (minor)
Location: /api-reference/gateways/create-a-gateway
Problem: The create-a-gateway response returns both "gateway_status": "enabled" and "status": "enabled" on the same object, with no explanation of how the two differ or whether they can diverge.
Consequence: Developers don't know which field is authoritative or whether to branch on gateway_status vs status. Agents may key off the wrong one.
The fix: Document the distinction, or collapse to a single status field. If both must exist, state which is canonical and when they differ.
20. Endpoint titled "Get MCP connection URL" is actually a POST that connects (minor)
Location: /api-reference/instances/get-mcp-connection-url
Problem: The page titled "Get MCP connection URL" documents POST /v1/gateways/{gateway_id}/instances/{id}/connect — a POST to a /connect action, not a GET retrieval.
Consequence: The title implies an idempotent read; the verb and path imply a state-changing action. A developer scanning titles to find a read-only "get URL" call may invoke a connect action with side effects.
The fix: Rename the endpoint to reflect that it performs a connect action and returns the URL, or clarify it is safe/idempotent.
21. Role definitions drift between Quickstart and Organisation Settings (minor)
Location: /platform-docs/quickstart, /platform-docs/organisation-settings
Problem: The Quickstart (Step 3) describes roles as only "Admin or Member," while Organisation Settings defines three roles with a hierarchy: Owner, Admin, Member.
Consequence: A developer reading the Quickstart won't know the Owner role exists — and Owner is the only role that can delete the org or perform other destructive actions. Onboarding teams may misassign permissions.
The fix: List all three roles consistently wherever roles are mentioned, including the Quickstart.
22. Numbered step list is mis-rendered on the Auth Configs & Connections page (minor)
Location: /platform-docs/auth-configs-and-connections
Problem: The numbered connection-setup list skips a number — it jumps from "1" straight to "2 Name the Connection," with the "Select a server" step missing its number entirely.
Consequence: A developer following the steps may skip or misorder the unnumbered "Select a server" step, or assume a step is missing. On a page that governs auth setup, broken step ordering is easy to misfollow.
The fix: Fix the list markup so every step is numbered in sequence.
23. Playground model names are written with inconsistent word order (minor)
Location: /platform-docs/playground
Problem: The Playground model selector lists "Claude Sonnet 4.6" (family-then-number) alongside "Claude 4.5 Haiku" (number-then-family) — the second inverts the naming order, and likely should read "Claude Haiku 4.5."
Consequence: Inconsistent model naming makes it ambiguous which model is meant and looks like a typo; for a docs set this audit otherwise faults for naming inconsistency, it's the same defect in the UI copy.
The fix: Use a single consistent model-naming order (e.g. "Claude Haiku 4.5", "Claude Sonnet 4.6") everywhere model names appear.
What they do well
- The Airtable server page bundles inline error guidance ("If tools return
403or empty base lists, check required scopes…") and the exact OAuth callback URL — the kind of operational detail the API reference otherwise lacks. - Connection lifecycle and destructive-action semantics are spelled out clearly on the Auth Configs & Connections page (revoking deletes credentials immediately; deleting an auth config revokes every connection it created).
- An
llms.txtand a publishedopenapi.jsonexist, so the agent-readable scaffolding is present — the problem is consistency of what's inside, not its absence.
Top 3 recommendations
- Fix the tool-naming and slug chaos first. Establish one canonical identifier per tool (
HSPOT_*,GITHUB_*) and one slug casing (lowercase), then sweep every page — Quickstart, server pages, gateway pages, Logs, and all API examples — so the same tool is spelled the same way everywhere, and reconcile the 24-vs-229 HubSpot tool count. This is the single biggest source of silent agent failures. - Make the API examples executable. Correct
auth_method_type(oauth, notoauth2), remove the phantomis_defaultrequest field, fix the HubSpot example that ships GitHub credentials and scopes, and replace invented tool names so a copy-pasted request from the API guide succeeds on the first try. - Document the failure and security surface. Add per-endpoint error responses and bodies, define the
dynamic/custom↔ Dedicated/ToolRouter mapping precisely, document the sandbox meta-tools' isolation/authorization model, and publish a changelog — so developers and agents can handle errors, evaluate risk, and pick the right mode instead of guessing.