TeamCentral Specs
Project specs page. Visit RAIZOR for custom development info.

Technical specs · TeamCentral

How TeamCentral is built: one AI workspace, server-first

The stack, the request path, where data is stored and how it's reached, how each layer is secured, and where AI does the work: retrieval, routing between models through OpenRouter, and an MCP connector that brings it all into Claude and ChatGPT. Written for engineers and technical evaluators.

6 toolsplus Shared Links, in one app
16 MCP toolsOAuth 2.1, gated by plan
9 modelsreached through one OpenRouter API
178 endpointsall server-side, no client DB access
~190k linesTypeScript + Svelte
~900 testsVitest, alongside the code

01 · ArchitectureHow it fits together

TeamCentral is a single SvelteKit application rendered server-side on Netlify. Every request (from the web app, an AI assistant over MCP, a public share page, a webhook or a scheduled job) passes through one ordered set of server hooks before it reaches a route. Routes are the only code that touches data: the browser signs in and nothing more. Firestore is the system of record, Pinecone holds the search vectors, and model calls go out through OpenRouter.

Swipe sideways to see the whole diagram →

WHO CALLS IN EDGE · NETLIFY APP SERVER DATA Web app (browser) Claude / ChatGPT (MCP) Share-page visitors Inbound webhooks Scheduled jobs (cron) SvelteKit server One SSR function behind a CDN 1 · CSRF origin check 2 · Bot-probe filter 3 · Session cookie verify 4 · Auth guard: role, plan, org 5 · Security headers Server routes & actions 178 endpoints · Firebase Admin SDK only Meeting AssistantTeam Scheduler News ScannerBrandBot Prompt ManagerContact Directory MCP server · OAuth 2.1 · 16 tools Shared Links · sandboxed pages Firestore System of record ~60 collections Pinecone Vectors only meetings + contact profiles Cloudinary Images, logos, large files and pages OAuth tokens · webhooks prompt + retrieved context INTEGRATIONS Google CalendarOAuth · free/busy + events ZoomOAuth · creates meeting links FathomMeeting transcripts in StripeCheckout + signed webhooks ResendQueued email with retries ApifyLinkedIn post scans AI LAYER OpenRouter One OpenAI-compatible API Primary + fallback per task Gemini FlashGPT-5 family Claude SonnetGrok Fast Qwen3DeepSeek Pinecone Inference Embeddings (1024-dim) + reranking of candidates Query router (LLM) Picks the data path per question: exact, metadata, totals, semantic, hybrid The browser only signs in. Every read and write runs on the server under the signed-in user's identity, role and plan.

02 · StackWhat it's built with

A deliberately small set of managed services: one framework, one database, one vector store, one model gateway. There are no servers to run; the app ships as one serverless function plus static assets.

LayerTechnologyHow it's used
Front end
FrameworkSvelteKit, TypeScript, Svelte runesServer-rendered pages with form actions; client code holds UI state only.
UITailwind CSS + DaisyUITwo app themes (light default, dark), one signature blue-to-teal gradient, Lucide icons.
ContentMarked, DOMPurify, TurndownMarkdown in and out of AI answers, sanitized before it renders.
Server & hosting
HostingNetlifyCDN for static assets; the whole app runs as one server-side rendering function.
AuthFirebase AuthenticationClient SDK signs in, then trades its ID token for an httpOnly session cookie.
SchedulingExternal cron callersToken-protected endpoints for news scans, digests, the email queue and clean-up.
Data
DatabaseCloud Firestore (Admin SDK)System of record for users, orgs, meetings, prompts, billing state, logs and analytics.
Vector searchPinecone + Pinecone InferenceMeeting transcript chunks and contact profiles; embedding and reranking in the same service.
MediaCloudinaryAvatars, org logos, social images, design-system files and oversized share pages.
AI
Language modelsOpenRouter (OpenAI SDK)One API for every chat, routing and summarization call; models swap by setting, not code.
Assistant accessModel Context ProtocolA built-in MCP server so Claude and ChatGPT can use TeamCentral's tools directly.
Integrations
Calendar & videoGoogle Calendar API, ZoomFree/busy heatmaps, booking, and meeting links.
TranscriptsFathom webhook, email in, uploadMeetings arrive automatically or by hand and are indexed for search.
BillingStripeCheckout, three plans plus seat add-ons, monthly and yearly.
EmailResend + HandlebarsTemplated mail sent from a Firestore-backed queue with retries.
Web dataRSS, scraping, ApifyNews Scanner feeds and LinkedIn post scans.
Quality
ChecksVitest, svelte-check, ESLint, PrettierTests live next to the code they cover; type, lint and format checks before each release.

The codebase at a glance

Endpoints

178 server endpoints, 162 of them under the API.

Pages

53 pages, 45 with server-side loaders or actions.

Modules

106 server-only library modules, never shipped to the browser.

03 · DataHow data is stored and reached

Firestore holds the truth, including full meeting transcripts. Pinecone holds only vectors pointing back to Firestore records, so the search index can be rebuilt at any time. No browser code reads the database: every query runs in a server route with the Admin SDK, after the hooks have established who is asking.

System of record

Firestore

About 60 collections. Server loaders map every document field by field into typed objects and convert timestamps before anything reaches a page, so the client never sees raw database shapes.

Search index

Pinecone

Each meeting gets one "topic anchor" vector (title, summary, metadata) plus overlapping transcript chunks. Each user gets one contact-profile vector, re-indexed when the profile is saved.

Files

Cloudinary

Images and binaries. Small text files stay in Firestore; large design-system bundles and oversized share pages are offloaded to the CDN.

Browser

Local storage only

Model preference and a meetings cache for speed. Nothing authoritative lives in the browser.

What lives in Firestore

DomainWhat it stores
Identity & orgsProfiles, organizations, connections between users and orgs, sign-up codes, app settings, system prompts.
MeetingsTranscripts with AI-generated summaries, decisions and action items; pending meetings; recent chats.
BrandBot & ContactsConversations and messages, contact requests, design-system files.
Prompts & NewsPrompt library with folders and version history; RSS feeds, articles and scan caches.
SchedulingEncrypted calendar and Zoom connections, 15-minute availability blocks (start and end times only), share tokens.
MCP & sharingHashed access tokens, OAuth clients and codes, audit log, chat and article snapshots, hosted share pages.
OperationsBilling customers, webhook idempotency records, email queue, query analytics, daily metrics, error logs, health and locks.

Short-lived records (webhook receipts, MCP audit entries, chat snapshots) carry expiry dates and are cleaned up automatically.

Who can see what

Ownership checked on the server

Every record carries its owner (a user ID or org). Server routes filter on it in every query, and vector search results are re-loaded from Firestore under the caller's ownership before any text reaches a model. A search hit the caller doesn't own is dropped, never summarized.

Roles, plans and orgs

Four roles (user, org member, org admin, admin) decide which screens exist; the subscription plan and the active organization decide which tools and data a request can reach. Contact search only ever looks across the caller's own connections.

04 · SecurityDefense in layers

Each layer assumes the one outside it might fail. The rules are enforced in code review too: secrets come only from the platform's private environment, writes happen only in server code, and nothing sensitive is written to logs.

Edge filtersEvery request

Cross-site form posts are rejected by an origin check; known vulnerability probes are answered with a 404 before any app code runs.

IdentitySession

Firebase session cookies (httpOnly, Secure, SameSite=Lax) with an admin-set lifetime, verified on every request with revocation checks. Disabled accounts are signed out on their next request.

AuthorizationRole · plan · org

An auth guard resolves the user's role, subscription status and active organization before a route runs; tools the plan doesn't include simply aren't reachable.

Secrets at restTokens

Calendar and Zoom OAuth tokens are encrypted with AES-256-GCM. MCP tokens are stored only as SHA-256 hashes and shown once. Email links (unsubscribe, digest settings) are HMAC-signed and compared in constant time.

Inbound callsWebhooks · cron

Stripe and Resend webhooks are signature-verified, and Stripe events are de-duplicated. Scheduled-job endpoints require a secret token compared in constant time.

Abuse limitsRate limits

Per-route limits on sign-in, password reset, contact forms, AI chat (30 a minute per user) and MCP (per IP and per token). Sign-up and reset flows answer the same way whether or not an email exists.

Browser hardeningHeaders · sandbox

A Content Security Policy with an allowlist, HSTS with preload, no-sniff and a strict referrer policy. User-generated share pages render in a sandboxed, null-origin frame so their HTML can never reach the app.

05 · AIHow AI is used to make it work

AI shows up in two ways: as the product (chat over your meetings, brand-aware writing, news summaries) and as plumbing (deciding how to answer a question, naming and summarizing meetings). Every model call goes through one OpenRouter client, every task has a primary and a fallback model, and every call is logged with its cost.

Gateway

Why OpenRouter

One OpenAI-compatible API reaches Google, OpenAI, Anthropic, xAI, Qwen and DeepSeek models. Swapping or adding a model is a settings change, not a new SDK, and an outage at one provider falls through to another.

Admins choose the default model and the list users may pick from; the server refuses any model not on that list.

Cost

AI accounting

Each call records its token usage. Prices come from OpenRouter's live model list (cached for a day, with a built-in fallback table, plus OpenRouter's fee), rolled up per user, per tool and per day, so cost per tool is visible to users and admins.

Which model does what

TaskPrimaryFallbackWhy this pairing
Chat defaultGemini 2.5 Flashuser's pickFast, long context, low cost; users switch per conversation within the admin's allowed list.
Query routingClaude Sonnet 4.5GPT-5.2Strict JSON and careful date handling matter more than speed.
News summariesGemini 2.5 FlashGPT-4o-miniHigh volume, structured output, lowest cost per article.
Fast tasksGemini 3 FlashGrok 4.1 FastShort, latency-sensitive calls.
Meeting metadataGemini 3 FlashClaude Sonnet 4.5Summary, decisions, action items, red flags and sentiment from a transcript.
Meeting titlesGrok 4.1 FastGemini 2.5 FlashOne short, cheap call per meeting.

User-selectable chat models today: Gemini 2.5 Flash, Gemini 3 Flash, Grok 4.1 Fast, GPT-5 Mini, Qwen3 Next 80B and DeepSeek V3.2. The list changes as models improve.

Meeting Assistant: retrieval-augmented answers

  1. Ingest

    Transcripts arrive from Fathom, email or upload. An LLM writes the title, summary, decisions, action items and sentiment.

  2. Index

    One anchor vector per meeting plus 1,500-character chunks with 20% overlap, embedded in batches and stored with owner and date metadata.

  3. RouteLLM

    A router model reads the question and returns JSON: which data path (exact lookup, metadata, totals, semantic, anchors only, or hybrid), plus dates in the user's time zone, people and intent.

  4. Retrieve & rerank

    Vector search pulls up to 150 candidates; a reranker keeps the best 25, with a boost for recent meetings and meeting-level anchors.

  5. AnswerLLM

    Full records load from Firestore under the user's ownership, then the answer streams back with inline citations like [[Weekly sync, 2026-10-02]].

Retrieval funnel, per question

Questions like "how many meetings with Acme last quarter?" skip vectors entirely: the router sends them to an exact Firestore query, which is cheaper and always correct.

AI in the other tools

BrandBot

Builds its system prompt from the active org's brand training (overview, audience, offerings, tone, guidelines) or the user's own, plus global writing rules. Long conversations are trimmed oldest-first to stay within the model's context, and it notices when a chat drifts off topic.

News Scanner

Reads RSS feeds, scrapes each article (CSS selectors first, an LLM extractor if that fails, then an archived copy), and summarizes it to structured JSON with the low-cost model, retrying on the fallback.

Contact Directory

Semantic search over the profiles of the people you're connected to, then an AI chat that answers questions about your network from those profiles.

Team Scheduler

Deterministic where it counts: free/busy data from Google is cached in 15-minute blocks and drawn as a team heatmap, so availability is always exact.

06 · MCP connectorTeamCentral inside Claude and ChatGPT

TeamCentral runs its own Model Context Protocol server, so an assistant can look up a contact, find a meeting time and book it, pull a meeting summary or load brand context without leaving the chat. The assistant brings its own model; TeamCentral supplies the tools and the data, under the same permission checks as the app.

  1. Discover

    The assistant reads standard OAuth discovery documents and registers itself (Dynamic Client Registration).

  2. Consent

    The user signs in to TeamCentral and approves. PKCE (S256) is required, redirect URLs must match exactly, and codes work once within five minutes.

  3. Call tools

    Opaque, hashed access tokens (12 hours) bound to TeamCentral's MCP address; refresh tokens rotate safely. Every call is capped at 25 seconds and rate-limited.

  4. Audit

    Each call is logged without its parameters, results or token, and with a hashed IP address. Tokens can be revoked at any time.

16 tools, gated by plan

list_my_organizationslist_team_membersfind_contactget_contact_detailssearch_contactssend_emailfind_meeting_timesbook_meetinglist_promptsget_promptcreate_share_link get_brandbot_contextget_design_systemlist_recent_meetingsget_meetingget_news_digest

Long meeting transcripts are returned in pages, so an assistant can read a two-hour call in full.

07 · OperationsBackground work and design choices

With no servers of its own, TeamCentral runs background work as ordinary endpoints called on a schedule, each protected by a secret token. The news scan also takes a Firestore lock so two runs never overlap.

  • every minute
    Email queueSends queued mail in priority order, spaced to the provider's rate limit, with retries and a dead-letter state.
  • every 5 min
    Keep-warmKeeps the server function warm so the first click of the day is fast.
  • mornings, 15 min
    News scanScans feeds in small batches inside a time budget, so one slow site can't stall the run.
  • daily
    News digestBuilds and emails each user's summarized digest.
  • scheduled
    LinkedIn scan · reminders · clean-upPost scans, checkout reminders, and removal of expired snapshots and logs.
  • on demand
    Availability syncCalendar free/busy is fetched when a heatmap is opened, with a timeout, then cached.

Design choices worth knowing

  • Server-first data access. No client database SDK, so access rules live in reviewed TypeScript rather than in a separate rules language.
  • Firestore is the truth, vectors are an index. Losing the index loses speed, not data.
  • One model gateway. Models are chosen per task and replaced as better or cheaper ones appear, with no code change.
  • Routing before retrieval. An LLM decides whether a question needs vectors at all; counts and dates go to exact queries.
  • One function, managed services. Simple to deploy and cheap at low volume; the trade-offs are cold starts (hence keep-warm) and platform response-size limits.

Interested in collaboration or a custom installation?

I design and build custom apps like TeamCentral, from the first sketch to running in production. Tell me what you have in mind and I'll reply by email.

Get in touch →