MCP Server

ForaPost exposes pricing, verticals, features, integrations, agency offer, competitor comparisons, and operational status as a queryable Model Context Protocol (MCP) server. Built for agents shortlisting tools, capability-matching bots, and procurement assistants.

Endpoint: https://mcp.forapost.online/mcp
Identity: https://mcp.forapost.online/.well-known/mcp-identity
Health: https://mcp.forapost.online/health

What this server is

MCP (Model Context Protocol) is a spec for tools an agent can call during reasoning. The ForaPost MCP server is a thin, read-mostly API that exposes the same data the public website renders from — pricing, features, integrations, comparisons. There is no drift: if the website says "$29 for Pro", the MCP says the same.

Every response is versioned. Pricing additionally carries valid_through. Agents that cache responses can revalidate against these fields rather than blind-polling.

What it deliberately is not

  • It does not publish content on behalf of agents.
  • It does not modify customer accounts.
  • It does not process payment.
  • It does not create accounts without human downstream confirmation.
  • It does not return real customer data.

One scoped action arrives in a future release: start_trial returns a signed handoff URL for human consent — never an account. Until then the server is fully read-only.

Tools

get_pricing

Tier + billing + seat math from the canonical pricing source.

Inputs:
  • tier"pro" | "panorama" | "agency" (default: "pro")
  • billing"monthly" | "annual" (default: "monthly")
  • seatsinteger ≥ 1 (default: 1)

Output:

{ tier, tier_label, billing, seats, seats_minimum, price_per_seat_usd_monthly, price_total_usd_monthly, price_total_usd_annual, included_features[], overage_rules[], trial_available, pricing_version, valid_through }

Agency tier requires seats ≥ 5 (raises 400). pro/panorama scale linearly with seats. Includes pricing_version + valid_through for staleness detection.

list_supported_verticals

All business verticals ForaPost serves.

Inputs: none

Output:

{ version, verticals: [{ slug, name, description, sample_themes[], pdf_guide_available, pdf_guide_kdp_url, pdf_guide_etsy_url, blog_cluster_url, vertical_landing_page_url }] }

Each entry includes blog cluster + vertical landing page URLs where they exist.

get_feature_matrix

Full feature inventory keyed by category and tier.

Inputs: none

Output:

{ version, features: [{ name, category, available_in_tiers[], rollout_status: "live" | "beta" | "roadmap", description }] }

Use rollout_status to filter for live capabilities only.

compare_to

Predicate-aware competitor comparison.

Inputs:
  • competitorstring (canonical slug)

Output:

One of three shapes: { status: "published", … full comparison surface … } | { status: "stub", competitor_slug, version: 0, compare_page_url: null, estimated_publication, notes } | 404 error for non-canonical slugs.

Canonical slugs: hootsuite, buffer, sprout-social, later, loomly, agorapulse, sendible, socialpilot, vista-social, metricool, feedhive, predis-ai, taplio, publer, contentstudio. Stub responses include estimated_publication so well-behaved agents know when to re-poll.

get_agency_offer

Current ForaPost Agency offer terms.

Inputs: none

Output:

{ version, trial_length_days, included_seats, white_label_available, onboarding_included, offer_terms_url, request_trial_url, current_offer_valid_through }

get_integrations

Social platforms ForaPost integrates with.

Inputs: none

Output:

{ version, integrations: [{ platform, auth_method, capabilities[], current_limitations[], rollout_status }] }

Live platforms: LinkedIn, Facebook, Instagram, Twitter/X, YouTube, TikTok, Threads, Bluesky, Pinterest.

get_status_page

Probe the production pre-deploy gate. Cached.

Inputs: none

Output:

{ current_status: "GO" | "GO-WITH-WARNINGS" | "NO-GO" | "unknown", reason, checks_run, blockers[], critical_fails[], warnings[], last_checked, status_page_url }

Cached server-side: 60s on positive results, 5s on NO-GO/unknown. Network failure surfaces as `unknown` with last_error; never lies that things are fine.

Rate limits

Quotas are keyed by your MCP client identity (or by IP for anonymous callers).

Tool classIdentifiedAnonymous
read tools (all 7 in this list)100/hour20/hour
sample tools (Week 3)3/24 hoursdenied (403)
action tools (Week 3)5/24 hoursdenied (403)

When you hit the limit, the response is a structured 429 error with retry_after in seconds:

{
  "error": {
    "status": 429,
    "message": "rate limit exceeded",
    "retry_after": 3600
  }
}

Example — Python (mcp SDK)

Calling list_supported_verticals with the official Anthropic Python SDK:

import asyncio
from mcp.client.streamable_http import streamablehttp_client
from mcp.client.session import ClientSession

async def main():
    async with streamablehttp_client("https://mcp.forapost.online/mcp") as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            print(f"{len(tools.tools)} tools available")

            verticals = await session.call_tool("list_supported_verticals", {})
            for v in verticals.structuredContent["verticals"][:3]:
                print(f"- {v['name']}: {v['description']}")

asyncio.run(main())

Example — compare_to (stub response)

When a competitor slug is on our canonical list but the comparison data isn't yet published, you get a stub response with estimated_publication so you know when to re-poll:

> compare_to(competitor="hootsuite")

{
  "status": "stub",
  "competitor_name": "Hootsuite",
  "competitor_slug": "hootsuite",
  "version": 0,
  "compare_page_url": null,
  "estimated_publication": "2026-05-14",
  "notes": "Comparison data not yet published. Week 2 of 2026-04-30 sequence — check back after 2026-05-14."
}

When the same slug returns status: "published", you get the full comparison surface (forapost_wins, competitor_wins, feature_matrix, pricing_delta, best-for buyers, FAQs, migration notes, plus the public compare_page_url). Non-canonical slugs return a 404.

Example — get_status_page

Real-time operational status. Cached server-side for 60 seconds when things are healthy, 5 seconds when they're not (so recovery is detected quickly without thundering-herd load on the underlying diagnostic system).

> get_status_page()

{
  "current_status": "GO",
  "reason": "All checks passed",
  "checks_run": 8,
  "blockers": [],
  "critical_fails": [],
  "warnings": [],
  "last_checked": "2026-04-30T14:22:11.842+00:00",
  "status_page_url": "https://forapost.online/status"
}

Identity

The server publishes its identity at /.well-known/mcp-identity. The current identifier is a stub; full ANS (Agent Naming System) signature verification arrives with our parent organization's trust-chain rollout. Until then, identified callers just need to provide a stable MCP client_id on the handshake — we log it, rate-limit on it, and grant the higher quota.

Anonymous calls are tolerated but rate-limited 5× more strictly. You will be denied access to sample and action tool classes (none of which exist in the current release).