https://firstsales.io/mcp/ without a FirstSales account.
Use this Product MCP resource URI:
The synchronized release manifest has
release_ready: true. The released
catalog is read-only and bound to the manifest’s authorization catalog epoch.
Runtime reachability and the tools visible to one connection still depend on
deployment attestation, tenant features, and its live OAuth Grant.2026-07-28 contract and the isolated legacy
2025-11-25 compatibility contract, which also accepts 2025-06-18 clients.
Agent operating checklist
Configure an agent or MCP client in this order:- Confirm the endpoint is the canonical resource:
https://api.app.firstsales.io/mcp. - Obtain an OAuth bearer token whose audience/resource is exactly that URI.
- Call
server/discoverfirst, then treattools/list,resources/list, andprompts/listas the authority for the current connection. - Expect only the tenant- and Grant-scoped subset of the Released-tool catalog below, not the whole parity artifact.
- Prefer CLI or direct Developer API calls when your workflow needs a capability that is not present in discovery.
Modern endpoint
The modern runtime implements stateless Streamable HTTP. Each request or notification is one UTF-8 JSON-RPC message in anapplication/json POST; batch arrays
are rejected. The client Accept header may list application/json and
text/event-stream, but either media type is sufficient. The response is one JSON
object or a request-scoped SSE stream that closes after its final response. Accepted
notifications return 202 without a response body. The legacy GET stream requires
Accept: text/event-stream.
There is no modern MCP session or initialize handshake. Every request must carry
io.modelcontextprotocol/protocolVersion and
io.modelcontextprotocol/clientCapabilities in params._meta; clientInfo is optional
and never authority. The MCP-Protocol-Version and Mcp-Method headers must agree with
the body, and targeted calls also require a matching Mcp-Name. Modern GET and
DELETE return 405. CORS OPTIONS is handled outside both protocol codecs.
Aggregate discovery uses server/discover. After release attestation, clients should
use discovery to learn the admitted surface; do not assume the MCP registry is a mirror
of the OpenAPI or CLI command catalog.
Authorization
When release-attested, the endpoint requires an OAuth access token for the canonical resource URI, sent as a bearer token:https://app.firstsales.io. Its public
OAuth metadata and endpoints are:
resource=https://api.app.firstsales.io/mcp. The authorization-code flow uses state,
PKCE S256, and RFC 9207 iss; clients validate the returned issuer before exchanging
the code.
Register a public MCP client
Use a pre-registered client when FirstSales supplies one. Otherwise, prefer a Client ID Metadata Document (CIMD). Use the HTTPS URL of the document as theclient_id; the
document must repeat that exact URL, list the exact redirect URIs, and declare a public
authorization-code client with token_endpoint_auth_method: none,
response_types: ["code"], and PKCE S256. FirstSales fetches and validates the
document again for each authorization request.
For clients without CIMD support, use Dynamic Client Registration (DCR) as a
compatibility fallback. Discover registration_endpoint from the selected FirstSales
issuer and keep the returned client_id bound to that issuer. DCR clients are also
public authorization-code clients and must use PKCE S256; they do not receive or send
a client secret. Public MCP clients cannot register or exchange tokens with the
client_credentials grant.
If authorization with a client metadata document fails with invalid_client and
Unable to validate client metadata document., register with DCR instead. In Codex,
pass --oauth-client-registration dcr to codex mcp login; see
Codex and Claude Code.
Consent, authority, and token lifetime
If the user is not signed in, FirstSales preserves the signed OAuth continuation while sending them through the normal login flow. The consent flow lets the user choose from their currently accessible organizations and workspaces. It restores the saved server selection on reload, records accepted OAuth tiers per organization and autonomy per workspace, and issues authority only for the approved selection. The Approve and Deny actions show an immediate live progress label, lock the consent controls, and ignore duplicate submissions. If an authorization step fails, the controls are restored and the current organization, workspace, tier, and autonomy selection remains available for retry. The token must satisfy the configured issuer, audience/resource, expiry, and scope and must carry the delegated capability required by the requested tool. Dashboard session cookies and Developer API keys are not accepted by product MCP. OAuth tiers aremcp:access, mcp:write, mcp:destructive, and mcp:financial;
mcp:access is the default and is required before any optional tier. Per-workspace
autonomy modes are observe (“Observe only”), draft (“Draft changes”),
execute_within_policy (“Execute within policy”), and supervised (“Supervised”);
observe is the default. These values bound authorization only and never release a
capability.
Access tokens expire after 10 minutes. A client receives no refresh token unless it
opts in with offline_access and pairs that scope with the refresh_token grant.
Refresh tokens rotate on use and expire within 30 days; reuse invalidates the token
family. Refresh and access tokens remain bound to the client, MCP resource, and current
tenant grant. Use the authorization server’s revocation endpoint to revoke a token;
revoking an MCP connection or organization grant also makes its authority fail closed.
Legacy compatibility
The2025-11-25 compatibility path uses its own durable session lifecycle over
POST, GET, and DELETE. A legacy session begins with initialize. When
params.protocolVersion is exactly 2025-11-25 or 2025-06-18, the server echoes that
version. For any other requested version it answers with 2025-11-25, following the
MCP lifecycle negotiation rule, and the client decides whether to continue. Subsequent
requests must carry the issued legacy session identifier. Both legacy versions receive identical responses; the lane
emits no field newer than 2025-06-18. Malformed or contradictory modern markers never fall
through to this codec. Keep the legacy handshake separate from the baseline for new
integrations.
Discovery surface
server/discoverfor aggregate modern discoverytools/listresources/listresources/templates/listprompts/list
capabilities/capability-parity-report.v1.json owns the complete
released catalog. Its summary.mcp_eligible_count and eligible entries under
rows[].mcp generate the visible Released-tool catalog below. After release
attestation, tools/list returns the narrower intersection allowed
by the current tenant features, OAuth Grant, and live authorization. The released
catalog is read-only; no product MCP write, destructive, financial, or approval-backed
action is released.
Released-tool catalog
This generated catalog contains exactly 17 parity-eligible tools. A tenant sees only the subset allowed by its live OAuth Grant and feature access.
server/discover or tools/list is authoritative for the current connection. Input and output JSON Schemas are returned by those discovery methods.
Machine authorities
- Capability parity report — exact compiled/eligible tool set, tenant context, bounds, and proof.
- Release manifest — bundle, authorization catalog epoch, release state, and contract hashes.
- Canonical OpenAPI — REST operation schemas linked by the operation IDs above.
capability_catalog resource, the operation_status
resource template, and the safe_campaign_review prompt. Resources and prompts are
first-class discovery surfaces. They do not mirror the OpenAPI or CLI registries.
Task and Operation foundation
Tasks are the optionalio.modelcontextprotocol/tasks extension and activate only when
a modern client advertises that extension in its per-request capabilities. A tool that
crosses its synchronous limit may project a durable Operation as a Task only when Tasks
are negotiated. tasks/get, tasks/update, and tasks/cancel remain behind the same
release and authorization gates. The runtime also implements an
operation_status resource template, but no current product MCP tool starts
long-running or approval-backed work. These methods define the contract for future
actions; current tools do not use them.
Write tools
No write tool is released today; the released catalog above is read-only. These write tools are built and will be released one at a time. Each has its own capability, and each call records an audit row with surfacemcp.
Idempotency keys for MCP writes are scoped to the grant. Direct Email tools (draft,
send, schedule, cancel) are planned; no MCP tool will approve a Direct Email.
Protocol notes
- Modern clients must use the per-request contract instead of the old
initialize/sessionhandshake. - Modern
Mcp-Session-IdandLast-Event-IDvalues are ignored; they never select state, authority, or replay. - Invalid
Host,Origin, protocol, media type, or authorization values fail closed. - Tool execution errors are returned as MCP tool results with
isError: trueso an agent can recover without treating a business error as a transport failure.
Transport and authorization errors
The HTTP boundary returns stable error codes before JSON-RPC dispatch:
The response also includes the applicable
WWW-Authenticate challenge for bearer-token
and scope failures. After dispatch, malformed JSON-RPC requests use JSON-RPC errors.
Tool-level API, input, and policy failures return a completed tool result with
isError: true.
Global limits
The runtime applies these limits in addition to the per-tool bounds in the catalog:
Schemas use JSON Schema 2020-12 and local JSON Pointer references. The server rejects
network references and descriptors or results that exceed these limits.