From REST to MCP.
Eight progressively-deeper integration levels.
Lower levels are zero-magic and let you ship in an hour. Higher levels reduce the integration burden your team carries, whether through a hosted widget, a framework abstraction, or an agent that writes the integration for you. Choose the rung that matches what your team can carry today, not the one that sounds most ambitious.
Eight rungs. Each one adds capabilities to the rung below.
L0 is the foundation, direct API access via REST and seven typed SDKs. L1 (Wernicke) embeds a hosted conversational widget onto your platform. L2 (Glia) is framework middleware. L3 generates the integration on install; L4 (Broca) maintains it over time. L5 through L7 are the destination, agents that observe, infer, and negotiate the integration on their own. Each rung carries a shipping target on the right, concrete quarters for the rungs in active build, "horizon" for the ones that depend on operational data we don't have yet.
| # | name | what it adds | status |
|---|---|---|---|
| L0 | API access | Direct HTTP via REST or any of seven typed SDKs (TypeScript, Python, Go, Java, Ruby, PHP, Rust). The foundation everything else builds on. | q3 2026 |
| L1 | Wernicke (campaign creation) | Embedded conversational widget. Three lines of code on your platform; advertisers describe campaigns in 3-5 messages. | q4 2026 |
| L2 | Glia (framework middleware) | Drop-in for Express, Next.js, Rails, Django, FastAPI. The integration weaves itself into the request lifecycle. | q1 2027 |
| L3 | Init wizard |
npx @gortex/init, schema-aware code
generator. Scans your stack and writes the integration.
|
q1 2027 |
| L4 | Broca (pr generation) | An agent opens complete pull requests for new surfaces. Code, tests, config, all in one PR. | 2027 |
| L5 | Cerebellum (ci drift repair) | When your codebase evolves in ways that break the integration, Cerebellum opens a follow-up PR with the fix. | horizon |
| L6 | Cerebrum (runtime inference) | No config file. Cerebrum observes traffic, infers your feature schema, adjusts hydration on its own. | horizon |
| L7 | Agent-to-agent (over mcp) | Your engineering agent discovers, negotiates, and integrates Gortex without human-written code. | horizon |
What each level looks like in your codebase.
Each level has its own integration shape, its own time-to-ship, and its own ongoing maintenance cost. The code samples below show realistic representations of what the integration touches, not full production examples, but enough to evaluate whether the level fits your team.
The ground floor. Direct API access via REST or any of seven typed SDKs, TypeScript, Python, Go, Java,
Ruby, PHP, Rust. The REST endpoint at api.gortex.ai/v1/decide accepts a JSON body
describing the recipient, the surface, and the candidate set, and returns a ranked array plus a
sponsored array with the decision metadata. Authentication is a bearer token; rate limits are
per-API-key sliding windows; the request and response schemas are stable and versioned in OpenAPI 3.1.
The SDKs are typed wrappers generated from the same spec, with automatic retry, backoff, telemetry, and
structured errors baked in.
Use raw REST if you're on an unsupported language, you want control over every byte, or your environment has a tight dependency footprint (Cloudflare Workers, Deno Deploy, edge functions). Use the SDK if your team writes in one of the seven supported languages and wants the operational hygiene built in, the same surface area as REST, with type safety, structured errors you can pattern-match on, and retry semantics already handled. Both modes are reversible into any higher level without throwing away the integration.
$ curl https://api.gortex.ai/v1/decide \ -H "Authorization: Bearer $GORTEX_KEY" \ -H "Content-Type: application/json" \ -d '{ "recipient": { "id": "u_7821" }, "surface": { "name": "profile_discovery" }, "candidates": [ { "id": "p_001" }, { "id": "p_002" } ], "slots": { "monetized": [3, 7] } }' // 200 OK · 78ms { "ranked": [...], "sponsored": [...], "decision_id": "d_01HXZ..." }
import { Gortex } from '@gortex/sdk' const gortex = new Gortex({ apiKey: process.env.GORTEX_KEY }) const decision = await gortex.decide({ recipient: { id: 'u_7821' }, surface: { name: 'profile_discovery' }, candidates: profiles.map(p => ({ id: p.id })), slots: { monetized: [3, 7] }, }) console.log(decision.ranked) // ['p_005', 'p_002', ...] console.log(decision.sponsored) // [{ slot: 3, item_id: 'p_007', ... }]
The simplest integration that adds advertiser-facing UX. Wernicke embeds onto any partner's surface as a
hosted widget, a script tag and a <button> element, and when an advertiser clicks the
button, a modal opens with a conversational interface that walks them through campaign creation in 3-5
questions. The pattern is borrowed directly from Stripe Checkout: the partner platform doesn't build any
campaign-creation UI, the advertiser doesn't learn the campaign management surface, and Gortex handles
everything in between. What appears in the partner's environment is a fully-formed campaign object,
written through the Pituitary campaign management system.
The right level for partners who want to offer monetized placements, boosts, uplifts, sponsored slots, without building any advertiser-side machinery themselves. Most consumer platforms don't have a campaign-creation UX team, and don't want to maintain one; Wernicke lets them launch monetized placements the same week they integrate. The right level for advertisers too: they describe what they want in plain language ("reach designers in the bay area for two weeks with a $200 budget") and Wernicke translates that into the structured campaign object. The translation step is where the system earns its name, Wernicke's area in the brain handles language comprehension, and that's exactly what this widget does: comprehend the advertiser's intent and produce a formal campaign structure.
The same widget works for every format. Boosting a profile, sponsoring a post, promoting a product, the
embed code is identical, just with a different data-target-type. Hosted means partners
don't carry the operational weight of a conversational AI integration, and don't have to update their
codebase when Wernicke's questions or prompts evolve.
// 1. PARTNER EMBED, three lines on your creator/profile page <script src="https://js.gortex.ai/v1/wernicke.js"></script> <button data-gortex-wernicke data-target-type="profile" data-target-id="p_001"> Boost this profile </button> // 2. ADVERTISER CONVERSATION, what opens when the button is clicked wernicke: what's the goal of this campaign? advertiser: get more designers to find my photography portfolio wernicke: who are you trying to reach? advertiser: designers and creative directors in the bay area wernicke: budget and timeline? advertiser: $200 over two weeks wernicke: creating campaign... → target: profile_discovery, slots 3 + 7 → budget: $200 over 14d, surge enabled → live in <5 seconds
The integration weaves itself into the framework's request lifecycle. Server-side adapters exist for Express, Next.js, Fastify, Rails, Sinatra, Django, FastAPI, and Spring Boot; client-side components ship for React, Vue, and Svelte to handle the disclosure-badge rendering. The unifying abstraction is the glia, a configuration object that ties the surface name, the candidate source, the slot policy, and the disclosure-render hook together in one place.
defineGlia() is the config builder; the framework middleware then wires it into the request
path so that the ranked output is available on the response object without your route handler doing the
request/response juggling. The right level for teams with an established stack that want to
minimize bespoke integration code, this is the level where most production deployments live.
import { defineGlia, withGortex } from '@gortex/next' import { db } from '@/lib/db' const glia = defineGlia({ surface: 'home_feed', candidates: async (req) => { const userId = req.auth.userId return await db.posts.findRecentForUser(userId, { limit: 50 }) }, slots: { monetized: [3, 7] }, }) export const GET = withGortex(glia)(async function feed({ ranked, sponsored }) { return Response.json({ items: ranked, ads: sponsored }) })
One command, schema-aware code generation. npx @gortex/init inspects your codebase to
identify your framework and ORM, scans your database schema to discover candidate sources (tables that
look like posts, profiles, products, items), asks three to five disambiguating questions interactively,
and writes a complete L2 integration into your repository, the glia config, the middleware wiring, the
type definitions, the env-var scaffolding. Time-to-first-decision goes from "an afternoon" to "two
minutes."
The right level for greenfield projects or for teams adopting Gortex who want the integration to appear without having to read the L2 documentation first. The wizard is opinionated, it generates the integration the way the docs would tell you to write it, no more and no less, which means the resulting code is also the canonical reference for how an L2 integration is supposed to look.
$ npx @gortex/init [gortex] welcome, let's get you wired up. [gortex] detected: next.js 14.2, postgres 16, drizzle orm [gortex] scanning schema for candidate sources... [gortex] found: posts (1.24M rows), profiles (340K rows), comments (4.1M rows) [gortex] which surface do you want to integrate first? > home_feed [gortex] which candidate source for home_feed? > posts [gortex] generating glia config... ✓ created gortex.glia.ts ✓ created app/feed/route.gortex.ts ✓ updated next.config.js ✓ updated .env.local (added GORTEX_KEY placeholder) [gortex] integration complete. run `pnpm gortex dev` to test.
Where the integration becomes ongoing rather than one-shot. L3 handles the first
integration; L4 handles every subsequent change. gortex broca add-surface opens a complete
pull request against your repository, analyzing the codebase, identifying where the new surface should
be integrated, writing the route handler and the glia config, generating an integration test, and
submitting it for human review.
The agent does the work a senior engineer would do during a "add Gortex to /search" task, read the existing /home_feed integration as a reference, mirror the patterns, write the test that mirrors the existing test, open a PR with a description that explains what changed and why. The output is a normal pull request that a human reviews and merges. The right level for teams already running L2/L3 who want incremental additions to not require eng time.
$ gortex broca add-surface --name search_results [broca] analyzing repository (syncup/web @ main)... [broca] found existing gortex integration on home_feed [broca] identifying integration points for search_results... [broca] ├── app/search/route.ts (entry point) [broca] ├── lib/posts.ts (candidate source) [broca] └── components/PostCard.tsx (disclosure render) [broca] generating PR... ✓ PR #842 opened: "Add gortex to /search route" ✓ 4 files added, 2 modified, 1 integration test added ✓ https://github.com/syncup/web/pull/842 [broca] human review recommended. tag @gortex-broca in the PR for follow-ups.
The CI agent that keeps the integration in sync as the surrounding codebase evolves. L4 generates a one-shot PR; Cerebellum runs continuously, watching for the moments when a schema migration, a route rename, a type update, or a dependency bump quietly breaks the Gortex integration. When drift is detected, Cerebellum opens a follow-up PR with the fix, same code-author UX as Broca, but reactive rather than proactive.
The problem Cerebellum solves is the one that defeats most "set it and forget it" integrations in real production codebases: the codebase doesn't stand still after the initial integration ships. A column gets renamed, a model gets refactored, a framework upgrades, and the integration silently degrades until someone notices the broken behavior in production. Cerebellum catches these in CI before they merge, or in nightly scans before they ship. The right level for teams running Gortex at scale who want CI to handle integration maintenance.
name: gortex-cerebellum on: pull_request: schedule: [{ cron: '0 4 * * *' }] jobs: mend: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: gortex/cerebellum-action@v1 with: token: ${{ secrets.GORTEX_KEY }} # cerebellum opens follow-up PRs when it detects drift # between your codebase and the gortex integration. # commits as @gortex-cerebellum; tag in the PR for review.
No config file. Cerebrum observes the traffic flowing through your application at runtime, infers the candidate feature schema and recipient context dynamically, and adjusts the hydration pipeline as your data shape evolves. The opposite axis from L3's "infer at install time", this is "infer continuously, as production traffic shapes the model."
Cerebrum is the level where the integration stops being a thing you maintain and becomes a thing that maintains itself. The right level for large, evolving codebases where keeping the glia config in sync with the actual data shape is itself the bottleneck, typically platforms with hundreds of feature columns, multiple candidate tables, and ongoing schema churn. The tradeoff is reduced explicit control; you trust Cerebrum's inference rather than declaring what the schema is.
import { cerebrum } from '@gortex/cerebrum' // no glia config. cerebrum watches traffic, infers the candidate // feature schema and recipient context, and adjusts the hydration // pipeline as your data shape evolves. surfaces are still named // explicitly so observability stays clean. cerebrum.attach({ surfaces: ['home_feed', 'search_results', 'profile_view'], // explicit overrides are optional, most teams need none. })
The destination. Integration as a conversation between agents rather than a coding task for engineers. Your engineering agent, whatever you use, Claude, Cursor, an internal tool, the LLM behind your CI bot, connects to the Gortex MCP server, reads the capability descriptions, analyzes your codebase, and generates the integration on its own. The agent on your side does the work that L4's Broca does today, but it's your agent, talking to our agent, with no Gortex-side product involvement in the loop.
This is the level where the brand promise becomes "Gortex is whatever your agents need it to be." The
MCP server exposes the primitives, decide(), glia, the surface taxonomy, the
slot configuration, and the rest is negotiated. The right level for teams where most engineering work
already happens through agents, which is more teams every quarter. L7 is on the horizon, but the horizon
is moving toward us.
// you, to your engineering agent: > add gortex's decisioning to our /discover route // your agent, behind the scenes: → connects to gortex.ai/mcp → reads capability: "decide()" with required schema → reads capability: "glia" for next.js integration → analyzes your codebase → generates the integration → opens PR for human review // gortex-side: no product involvement in the loop. // the integration becomes a request to an agent rather // than a coding task for an engineer.