Skip to content

Commit ca4a71c

Browse files
authored
seo: emit FAQPage JSON-LD on /ai/, /platform/, /pricing/; repoint /mcp/ links to /ai/ (#18)
GSC follow-ups from this week's coverage review: 1) Search Appearance was empty because no page emits rich-result-eligible structured data, even though /ai/, /platform/, and /pricing/ all have FAQ sections. Layout.astro now accepts an optional `structuredData` prop (object or array). The three FAQ pages declare their Q/A array in frontmatter and pass a FAQPage block. Default SoftwareApplication is now only emitted on the homepage instead of every non-article page, which was the source of the duplicate-entity warnings. 2) Two blog posts still linked to the retired /mcp/ path, which meta-refresh-redirects to /ai/. Repointed directly to /ai/ so the PageRank flow lands on the canonical target without the redirect hop: - src/content/blog/what-is-an-mcp-gateway.md:138 - src/content/blog/why-agents-break-where-developers-cope.md:130 Layout type prop is still respected for blog posts (BlogPosting). Built locally; FAQPage / Question / Answer triples emit on the three target pages, SoftwareApplication only at /, BlogPosting only on articles.
1 parent b92643c commit ca4a71c

6 files changed

Lines changed: 140 additions & 7 deletions

File tree

src/content/blog/what-is-an-mcp-gateway.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,4 @@ The MCP gateway category is in the same place the API gateway category was in ar
135135

136136
If you are on a platform team and agents are not yet in your threat model, they are about to be. If you are on an AI product team and your agents are still calling internal APIs with hand-rolled tool servers, the shadow stack is already forming. The good news is the fix is cheap compared to the sprawl it prevents.
137137

138-
At Barbacane we are building one gateway that spans all three categories: API gateway fundamentals, outbound AI gateway for your LLM calls (via the `ai-proxy` dispatcher), and MCP gateway for agents calling your APIs. Open source, Rust-native, spec-first, composed from the same dispatcher and middleware primitives so the three layers share plumbing rather than compete with it. If that sounds like what you need, [the /mcp page](/mcp/) is the five-minute version of the MCP layer specifically. Otherwise, the ideas above hold regardless of which tool you pick. The categories matter more than the product.
138+
At Barbacane we are building one gateway that spans all three categories: API gateway fundamentals, outbound AI gateway for your LLM calls (via the `ai-proxy` dispatcher), and MCP gateway for agents calling your APIs. Open source, Rust-native, spec-first, composed from the same dispatcher and middleware primitives so the three layers share plumbing rather than compete with it. If that sounds like what you need, [the /ai page](/ai/) is the five-minute version of the MCP layer specifically. Otherwise, the ideas above hold regardless of which tool you pick. The categories matter more than the product.

src/content/blog/why-agents-break-where-developers-cope.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,4 @@ At Barbacane we build that platform on the assumption that this is where things
127127

128128
---
129129

130-
*Barbacane is open source (AGPLv3) and available at [github.com/barbacane-dev/barbacane](https://github.com/barbacane-dev/barbacane). If MCP and agent-readiness are on your roadmap, [the /mcp page](/mcp/) is the short version of how we approach it.*
130+
*Barbacane is open source (AGPLv3) and available at [github.com/barbacane-dev/barbacane](https://github.com/barbacane-dev/barbacane). If MCP and agent-readiness are on your roadmap, [the /ai page](/ai/) is the short version of how we approach it.*

src/layouts/Layout.astro

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ interface Props {
1111
tags: string[];
1212
};
1313
ogImage?: string;
14+
structuredData?: Record<string, unknown> | Record<string, unknown>[];
1415
}
1516
1617
const {
@@ -19,13 +20,14 @@ const {
1920
type = 'website',
2021
article,
2122
ogImage: customOgImage,
23+
structuredData: customStructuredData,
2224
} = Astro.props;
2325
2426
const siteUrl = 'https://barbacane.dev';
2527
const canonicalUrl = new URL(Astro.url.pathname, siteUrl).href;
2628
const ogImage = customOgImage || `${siteUrl}/og-image.png`;
2729
28-
const structuredData = type === 'article' && article
30+
const defaultStructuredData = type === 'article' && article
2931
? {
3032
"@context": "https://schema.org",
3133
"@type": "BlogPosting",
@@ -46,7 +48,8 @@ const structuredData = type === 'article' && article
4648
"mainEntityOfPage": { "@type": "WebPage", "@id": canonicalUrl },
4749
"keywords": article.tags.join(", "),
4850
}
49-
: {
51+
: Astro.url.pathname === '/'
52+
? {
5053
"@context": "https://schema.org",
5154
"@type": "SoftwareApplication",
5255
"name": "Barbacane",
@@ -56,7 +59,14 @@ const structuredData = type === 'article' && article
5659
"url": siteUrl,
5760
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
5861
"author": { "@type": "Organization", "name": "Barbacane", "url": siteUrl },
59-
};
62+
}
63+
: null;
64+
65+
const structuredDataBlocks = customStructuredData
66+
? (Array.isArray(customStructuredData) ? customStructuredData : [customStructuredData])
67+
: defaultStructuredData
68+
? [defaultStructuredData]
69+
: [];
6070
---
6171

6272
<!doctype html>
@@ -121,7 +131,9 @@ const structuredData = type === 'article' && article
121131
<meta name="twitter:image" content={ogImage} />
122132

123133
<!-- JSON-LD Structured Data -->
124-
<script type="application/ld+json" set:html={JSON.stringify(structuredData)} />
134+
{structuredDataBlocks.map((block) => (
135+
<script type="application/ld+json" set:html={JSON.stringify(block)} />
136+
))}
125137
</head>
126138
<body>
127139
<nav class="fixed top-0 left-0 right-0 z-50 nav-bg backdrop-blur-lg border-b border-themed">

src/pages/ai.astro

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,53 @@ paths:
7373
`;
7474
7575
const codeThemes = { light: 'github-light', dark: 'github-dark' };
76+
77+
const faq = [
78+
{
79+
question: "How is this different from Portkey or LiteLLM?",
80+
answer: "They are outbound-only AI gateways. Barbacane handles both directions plus API gateway fundamentals, from one spec, with one middleware chain. A full comparison is published at /blog/barbacane-vs-portkey-litellm/.",
81+
},
82+
{
83+
question: "Which LLM providers are supported on the outbound side?",
84+
answer: "OpenAI, Anthropic, and Ollama out of the box, with pinned upstream API versions. Any OpenAI-compatible server (vLLM, TGI, LocalAI, Azure OpenAI, self-hosted inference) works via provider: openai plus a custom base_url.",
85+
},
86+
{
87+
question: "Which MCP transport is supported on the inbound side?",
88+
answer: "JSON-RPC 2.0 over HTTP POST on /__barbacane/mcp. Session termination via DELETE on the same path.",
89+
},
90+
{
91+
question: "Can I adopt one direction without the other?",
92+
answer: "Yes. The two directions are independent. You can run Barbacane as an outbound-only AI proxy, an inbound-only MCP gateway, or both, depending on which x-barbacane-* extensions your spec uses.",
93+
},
94+
{
95+
question: "Do the AI governance middlewares apply to both directions?",
96+
answer: "Yes. ai-prompt-guard, ai-token-limit, ai-cost-tracker, and ai-response-guard compose around any dispatcher. The same four middlewares govern outbound LLM calls and inbound MCP tool calls, so your cost attribution, token caps, and scrubbing policies live in one place.",
97+
},
98+
{
99+
question: "Do I have to rewrite my existing APIs?",
100+
answer: "No. Add x-barbacane-* extensions to your existing OpenAPI spec. Barbacane compiles it into an artifact that speaks both regular HTTP and MCP to the same upstream services.",
101+
},
102+
{
103+
question: "Does authentication pass through?",
104+
answer: "On the inbound side, the Authorization header from the MCP request is forwarded into the internal dispatch; your jwt-auth, apikey-auth, or OAuth2 middleware validates it like any other request. On the outbound side, provider credentials stay in dispatcher config and never leave it.",
105+
},
106+
];
107+
108+
const faqStructuredData = {
109+
"@context": "https://schema.org",
110+
"@type": "FAQPage",
111+
"mainEntity": faq.map((item) => ({
112+
"@type": "Question",
113+
"name": item.question,
114+
"acceptedAnswer": { "@type": "Answer", "text": item.answer },
115+
})),
116+
};
76117
---
77118

78119
<Layout
79120
title="AI gateway for MCP and LLMs - Barbacane"
80121
description="Barbacane is the open-source AI gateway that handles both directions. Outbound: route LLM calls through OpenAI, Anthropic, or Ollama with provider fallback and policy routing. Inbound: expose your APIs to AI agents as typed MCP tools. Rust-native, spec-first, composed from dispatchers and middlewares."
122+
structuredData={faqStructuredData}
81123
>
82124
<!-- Hero -->
83125
<section class="section relative overflow-hidden">

src/pages/platform.astro

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,52 @@
11
---
22
import Layout from '../layouts/Layout.astro';
3+
4+
const faq = [
5+
{
6+
question: "How is this different from Kong, Apigee, or Tyk?",
7+
answer: "Those gateways ship with their own config DSL. Your OpenAPI spec is a parallel document you have to keep in sync with the gateway. Barbacane inverts that: the spec is the config. There is no second source of truth to drift from.",
8+
},
9+
{
10+
question: "Does it work with my existing OpenAPI specs?",
11+
answer: "Yes. Add x-barbacane-* extensions where you need gateway behaviour. Existing fields (security schemes, parameters, responses) are already interpreted. Specs stay portable to other tools.",
12+
},
13+
{
14+
question: "Can I add custom logic?",
15+
answer: "Yes, via WebAssembly plugins. Barbacane ships a full suite of official plugins and lets you write your own in any WASM-compiling language. Plugins are sandboxed, so a faulty plugin cannot crash the gateway.",
16+
},
17+
{
18+
question: "How does it deploy?",
19+
answer: "A compiled artifact is a single binary. Run it anywhere: Kubernetes, bare metal, on-prem VMs, edge locations, air-gapped environments. The control plane and data planes are independent, so data planes keep serving even if the control plane is offline.",
20+
},
21+
{
22+
question: "AGPLv3. Can I use it commercially?",
23+
answer: "Yes. Small teams and non-profits get a free commercial license. Larger organisations can buy a paid commercial license. Either way, every feature is open source, no gated enterprise tier. See /pricing/ for details.",
24+
},
25+
{
26+
question: "Does it support event-driven systems?",
27+
answer: "Yes. Barbacane reads AsyncAPI specs and bridges HTTP to Kafka, NATS, or AWS Lambda. The same spec-first, compile-safe workflow applies.",
28+
},
29+
{
30+
question: "Does this extend to AI traffic?",
31+
answer: "Yes. The same spec-first model covers outbound LLM routing (via the ai-proxy dispatcher) and inbound MCP for AI agents. Platform teams often use Barbacane for all three on the same gateway. See /ai/ for that side of the story.",
32+
},
33+
];
34+
35+
const faqStructuredData = {
36+
"@context": "https://schema.org",
37+
"@type": "FAQPage",
38+
"mainEntity": faq.map((item) => ({
39+
"@type": "Question",
40+
"name": item.question,
41+
"acceptedAnswer": { "@type": "Answer", "text": item.answer },
42+
})),
43+
};
344
---
445

546
<Layout
647
title="Spec-first API gateway for platform teams - Barbacane"
748
description="Barbacane turns your OpenAPI and AsyncAPI specs into your API gateway. No config drift, no reconciliation work, no hidden policy gaps. Rust-native, extensible via sandboxed WebAssembly plugins, control and data plane split."
49+
structuredData={faqStructuredData}
850
>
951
<!-- Hero -->
1052
<section class="section relative overflow-hidden">

src/pages/pricing.astro

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,45 @@
11
---
22
import Layout from '../layouts/Layout.astro';
3+
4+
const faq = [
5+
{
6+
question: "Is Barbacane really free?",
7+
answer: "Yes. All features are available to everyone with no gating. The source code is published under AGPLv3, which is free to use as long as you comply with its copyleft terms. If you cannot comply with AGPLv3 (e.g. you want to run it as a managed service without publishing modifications), a commercial license is free for small teams (up to €1M ARR, 10 employees) and non-profits.",
8+
},
9+
{
10+
question: "What if I do not need paid services?",
11+
answer: "That is perfectly fine. Use Barbacane freely, contribute to the project if you can, and reach out when you need help. Our documentation, GitHub issues, and community channels are available to everyone.",
12+
},
13+
{
14+
question: "Can you help with compliance requirements?",
15+
answer: "Yes. Our consulting packages include compliance reviews for SOC 2, GDPR, HIPAA, and other frameworks. We help you configure Barbacane's logging, security policies, AI governance middlewares, and audit trails to meet your requirements.",
16+
},
17+
{
18+
question: "Does this cover AI and MCP workloads?",
19+
answer: "Yes. Barbacane's AI gateway capabilities (ai-proxy dispatcher, AI governance middlewares) and MCP gateway capabilities are part of the same software. The same licensing and services apply, whether you are using Barbacane for outbound LLM routing, inbound agent tool exposure, or as a full API gateway.",
20+
},
21+
{
22+
question: "Do you offer on-premise deployment?",
23+
answer: "Barbacane is designed to run anywhere: on-prem, in your cloud, at the edge, or air-gapped. We can help you design and implement the deployment architecture that fits your infrastructure and security requirements.",
24+
},
25+
];
26+
27+
const faqStructuredData = {
28+
"@context": "https://schema.org",
29+
"@type": "FAQPage",
30+
"mainEntity": faq.map((item) => ({
31+
"@type": "Question",
32+
"name": item.question,
33+
"acceptedAnswer": { "@type": "Answer", "text": item.answer },
34+
})),
35+
};
336
---
437

5-
<Layout title="Barbacane pricing: open-source AI and MCP gateway, commercial license available" description="Barbacane is open source under AGPLv3. A commercial license is free for small teams and non-profits, paid for larger orgs. Same software either way - spec-first AI, MCP, and API gateway.">
38+
<Layout
39+
title="Barbacane pricing: open-source AI and MCP gateway, commercial license available"
40+
description="Barbacane is open source under AGPLv3. A commercial license is free for small teams and non-profits, paid for larger orgs. Same software either way - spec-first AI, MCP, and API gateway."
41+
structuredData={faqStructuredData}
42+
>
643
<!-- Hero -->
744
<section class="section">
845
<div class="container-custom">

0 commit comments

Comments
 (0)