[MORSALIN]
← All work
Case studyOwn product · Nuxt SSR · MCP · Client portal

This Site: Services, AI Access & Client Portal

morsalin.online is more than a portfolio. One typed catalog of 50 services feeds every page, the AI-readable files, a public MCP server and the on-site assistant. Behind it is a client portal for proposals, invoices, plans and payments, built so a one-person practice runs without admin overhead.

The hard part is not the pages. It is keeping 50 fixed prices identical everywhere they appear, making them readable by AI assistants, and running the whole engagement, from proposal to payment, without a back office.

Role
Product, design, engineering & ops
Domain
Services site · client portal
For
Small businesses · agencies
Status
Site live · portal ready
The problem
A one-person practice needs to be found by people and AI assistants, quote consistent prices everywhere, and run proposals, invoices and payments without an office.
What was built
Morsalin built a Nuxt site where one typed service catalog feeds every page, the AI files and a public MCP server, plus a client portal for the whole engagement from proposal to payment.
The result
The site is live, with free tools and AI access. The portal is built, security-reviewed and tested by 466 checks in CI, and launches with the first client.
50services, one source
14service groups
7public MCP tools
59components with EOL dates
4free tools
1portal, proposal to payment
466API checks in CI
0axe violations
01The problem

A one-person practice that has to look, and run, like a studio.

01

Prices drift when they live in many places.

A services page, a pricing table, a PDF, an AI summary and a chatbot each quoting the same work will eventually disagree. For a fixed-price practice, a stale price is a broken promise.

02

Buyers now ask an AI first.

Many people ask ChatGPT, Claude or Perplexity who can help before they search. A site that only people can read is invisible to that step.

03

One person, no back office.

Proposals, approvals, invoices, payments, monthly plans and reminders all have to happen without a project manager or an accountant, inside a hard limit on hours.

02One source

Fifty services, one typed catalog, zero drift.

One typed catalog

Each of the 50 services is one typed record: who it is for, what is included and not, plans with fixed prices and timelines, process, FAQ and what to put in an inquiry.

Everything reads from it

Service and group pages, the pricing page, the scope builder, the sitemap, llms.txt, the MCP server and the on-site assistant are all generated from the same records, so they cannot disagree.

Live settings without a redeploy

Open client slots, the next start date and the founding-price counter live in the database and are edited in the admin. Every page and AI tool reads the same values.

Outcome pricing, stated once

Public pages show fixed prices per outcome. Hour budgets stay in a private playbook that never ships with the site.

03AI access

Readable by people, and usable by their AI assistants.

A public MCP server

Seven read-only tools (find a service, list, details, availability and terms, stack check, end-of-life dates, case studies) over stateless Streamable HTTP: a fresh server per request, nothing to leak between callers, and a rate limit per visitor.

WebMCP in the page

For agents running in the visitor’s own Chrome, the page registers the same read-only tools and describes the inquiry form. The agent can fill the form; only the visitor can send it.

llms.txt from the same data

Plain-text summaries of services, prices, guides and tools are generated on request from the catalog, so an AI crawler reads today’s prices, not last month’s.

An assistant that can’t invent prices

The on-site assistant is given the catalog as its context and told to quote only from it. Inquiries get a private AI-drafted summary for triage; nothing AI-written goes to a client unreviewed.

04Free tools

Useful on their own, and a clear next step when they find something.

Stack check

Paste a composer.json, package.json, Dockerfile or lockfile. Versions past or near end of life are flagged in the browser; the file is never uploaded.

Known vulnerabilities

For lockfiles, an opt-in check sends only package names and exact versions to OSV.dev and shows advisories by severity with the fixing version.

End-of-life dates

Security-support dates for 59 runtimes, databases, servers and frameworks, synced from endoflife.date by a script and shown with sources.

Laravel upgrade planner

Every step from an old Laravel version to the current one, with the PHP versions each step needs.

App safety check

A passive check of an AI-built app for exposed keys, public source maps and a readable .env or .git. It only reads what any browser can see.

05Client portal

The whole engagement, from proposal to payment.

Proposal to payment

Clients approve proposals and change requests online, get invoices with PDFs, and pay by bank transfer, which is reconciled with the invoice for them. Monthly plans bill themselves.

Work in the open

Milestones, updates, files, plan hours and conversations in one place, and a safe way to hand over passwords that never goes through email. It launches with the first client.

06Quality

Tested, reviewed and accessible, and it says so with numbers.

466 API checks on every push

Eight suites (sign-in, billing, lifecycle, collaboration, growth, payments, inquiries, email) run in CI against a fresh PostgreSQL, each with a fresh server, next to a smoke test of every sitemap page and an MCP handshake.

Reviewed for security before launch

The portal and public forms went through a structured security review. Every finding was fixed or deliberately accepted, and each fix has a regression check.

Accessible by default

Every public, portal and admin page is checked with axe in light and dark mode. Zero violations, with the contrast tokens fixed at the source rather than per page.

Calm releases

A green build is mirrored for Cloud Build, which builds the image. Going live is a separate, manual step, so nothing reaches production by accident.

07Key decisions

Every non-obvious choice, with its reason.

One catalog, many outputs

Consistency by construction is cheaper than consistency by review.

Read-only AI tools first

An agent can find, compare and check, but anything that commits the visitor, like sending an inquiry, stays with a person.

Stateless MCP

A fresh server per request means no session to hijack and nothing to clean up.

Nothing leaves the browser by default

The stack check runs locally; the vulnerability lookup is opt-in and sends names and versions only.

Bank transfer, reconciled for the client

No card processor fees or checkout to maintain, and anything unclear waits for a person rather than a guess.

Portal inside the same app

One codebase and one deploy: the right size for a practice capped at a few clients at a time.

Tests at the API boundary

Every access rule is proven where it is enforced, including the “not yours returns 404” cases.

Manual go-live

Builds are automatic; putting a build in front of clients is a decision.

08Outcome

Live, and ready for the first client.

Found by people and AI

Server-rendered pages, structured data, llms.txt, an MCP server and WebMCP.

Prices that never drift

One catalog feeds every page and every AI answer.

Free tools that qualify

Stack, end-of-life and vulnerability checks that end in a clear next step.

A practice in one portal

From proposal to payment and monthly plans, without a back office.

  • ✓Status: the public site is live. The portal is built, security-reviewed and tested, and launches with the first client.
  • ✓Proof for the services it sells: the MCP server, accessibility audits, portals and SaaS builds, and CI with real tests.
  • ✓The hard limits of a one-person practice (few clients at once, capped hours, async work) are built into the process and the portal, not left to willpower.
  • ✓Stated plainly, including the gaps: browser UI tests for the portal pages are not yet automated in CI; the page checks so far were done by hand with axe.

My role

It is my own product, so I made every call: the positioning and pricing model, the catalog and page design, the MCP and WebMCP interfaces, the portal’s data model and access rules, the payment matching, the test suites, the security review and the release pipeline. I did the coding with AI pair-programming, and reviewed and tested every change.

Stack

App
Nuxt 4 · Vue 3 · TypeScript · Tailwind CSS
Data
PostgreSQL · Prisma 7 · Zod
AI
MCP SDK · WebMCP · Gemini
Ops
Docker · Cloud Build · scheduled tasks
Nuxt 4Vue 3TypeScriptPostgreSQLPrismaMCPWebMCPllms.txtStructured dataClient portalsInvoicing & PDFsWebhooksAccessibility (WCAG 2.2)CI testingCloud Build

Need something similar?

The work in this case study maps to these fixed-price services.

Next

Want a portal, an MCP server or a site like this?