nikitenok.dev

Talkfirst after three weeks: a Telegram Mini App, an MCP server for ChatGPT and Claude, and one click from Google

How I built Talkfirst, a speaking-first language app: a Telegram Mini App, an MCP server for ChatGPT and Claude, Lithuanian A2 and Constitution exam practice, and honest numbers from my first SEO weeks.

Published
Projects
Talkfirst
Tags
talkfirst, mcp, seo, lithuanian

Talkfirst started from a simple idea: you learn a language by speaking it, and flashcards and quizzes are only scaffolding for the conversation. I wrote the first specs on September 23. By October 12 the product had its own domain, talkfirst.io, a Telegram Mini App, a web app, an MCP server for ChatGPT and Claude, a mock exam on the Constitution of Lithuania, and 31 SEO articles. In this post I go through what actually works, how it’s built, and what my numbers are. The numbers are small for now, and that’s part of the story too.

One core, many thin clients

I made the architecture call on day one of distribution work. There is one core and many thin clients around it. Account, vocabulary, flashcards, reviews, text-to-speech, conversations and progress are the same everywhere. A client is just one more place where someone meets the product for the first time.

At the start the core could do voice conversation with pause analysis, pronunciation, quizzes, vocabulary and progress, and it faced the outside world as a PWA and an MCP endpoint with widgets. Sign-up was invite-only, with no limits and no payments. I picked a Telegram Mini App as the first external client: sign-up goes through Telegram, and payment goes through Telegram Stars (Telegram’s in-app currency), so I don’t need a payment provider of my own.

Rollout order: web with programmatic SEO, Telegram, a browser extension, ChatGPT/MCP, Discord, app stores; WhatsApp, Slack and Teams go in the second wave.

Limits and money

A week later I added weekly limits. Free gets 35 voice minutes a week. Pro gets 140 minutes for 500 Telegram Stars. Limits reset on Monday in the course’s time zone. At the same time I started tracking costs per user. Based on that, I moved exam dialogue turns to a different model, and one turn now costs about $0.0005 instead of $0.014.

The unit economics still don’t add up, and I can see it. By my estimate, a Pro user who uses up the whole limit costs me about $8–13 a month. From Telegram Stars I get about $6.5. The question is open: cap TTS cache misses (audio that has to be synthesized fresh) for Pro, or raise the price. I have to decide before card payments go live. Right now Pro can only be bought with Stars in the bot. There’s already a spec for web payments with provider options.

Lithuanian: A2 and the Constitution

I’m learning Lithuanian myself, so this track got the most attention. I built the content from open sources:

  • the CCLL frequency lists;
  • example sentences from Tatoeba, with authors credited;
  • an A2 exam task bank following the program of NŠA (Lithuania’s National Education Agency), 77 tasks in the first version.

Separately, I made a “courier / driver” track in Lithuanian and Polish. It has four scenes, and the “at the door” scene is free. Written Lithuanian A2 shipped on October 7.

The mock exam on the basics of the Constitution of Lithuania is a bank of 200 questions, checked against the 2022 edition of the text. There are three modes: exam conditions, practice, and a mistakes review. Free gets one variant every 7 days and one section; Pro gets everything. The exam landing page has a demo that needs no sign-up.

While checking the bank I found an annoying generation artifact: the correct answer is often the longest one. That was the case in 98 of 200 questions. Someone preparing for the real exam would learn that hint in one evening. So I’m going to rewrite the wrong options.

MCP: Talkfirst inside ChatGPT and Claude

Besides Telegram and the web, you can plug Talkfirst into an AI assistant as an MCP server.

  • Protocol and sign-in. A remote server over Streamable HTTP, OAuth 2.1 with PKCE S256 and dynamic client registration. You sign in with an email code or through Telegram.
  • Tools. They open MCP Apps windows: pronunciation scoring, voice conversation with an AI partner, quizzes. Beyond the windows there’s a personal vocabulary with spaced repetition, audio lessons, a weekly plan and progress.
  • Registry. The server is published in the official MCP Registry as io.talkfirst/talkfirst. Other directories pick it up from there.

The most useful thing I learned about the hosts is about their limits, not their features:

  • Claude on mobile. MCP Apps windows in Claude on the web and desktop get microphone access. In the mobile app the WebView has no microphone, so speaking practice doesn’t work there.
  • ChatGPT directory. According to the docs, reviewing a submission takes 60–120 days. EU availability wasn’t confirmed at the time I looked into it.
  • ChatGPT plugin rules. A plugin can’t show pricing or push users to upgrade. So the server doesn’t offer Pro in any host: it states the limit as a fact and adds “more in the Talkfirst app”.

SEO without a CMS: honest numbers

I generate the guides with a script from sources in the landing page repo, no CMS. Right now that’s 31 articles in Russian, Ukrainian, English and Polish across 11 topics: Lithuanian and Polish, first phrases, B1 speaking exam topics, and so on. The technical SEO:

  • sitemap with hreflang;
  • canonical URLs with a trailing slash;
  • JSON-LD;
  • noindex on the app and the API.

One subtlety cost me time. The login page is allowed in robots.txt but returns noindex. The reason: a search engine doesn’t crawl a URL blocked in robots.txt. So it never sees the noindex either, and a bare URL in search results is worse than none at all.

Now the numbers. First full week in Google Search Console (September 28 – October 4): 1 click and 2 impressions. The only click came from the branded query “talk first”, position 2.

On October 4 two Search Console reports disagreed. The sitemap report: 56 URLs submitted, 0 indexed. The coverage report from the same day: Google knew about 60 pages, and here is where they were:

  • indexed: 12;
  • “Discovered – currently not indexed”: 38. Google hasn’t visited them yet; the domain is new and has no backlinks;
  • “Crawled – currently not indexed”: 8, including three “first phrases” guides.

Their markup is fine, I checked it live. My hypothesis: the texts in different languages are too similar, and for a young domain Google keeps only one version. That’s a hypothesis for now, not a conclusion.

For AI search engines I added llms.txt, Content-Signal in robots.txt, and a single brand node in JSON-LD. For directories I prepared 9 submissions: Product Hunt, AlternativeTo, SaaSHub, BetaList, Uneed, There’s An AI For That, Futurepedia, Glama and FindMini, a Telegram Mini Apps directory. I’m still deciding which of them are worth the money. Paid options range from $5 for priority to $497.

How it was built

Two streams of Claude Code agents did the work in one codebase: product and distribution. Distribution works on the server, product on the screens. Tasks pass between the streams as files, because sessions get replaced and a message between them can get lost.

Sharing one working tree burned us once. On September 24 the other stream’s commit swept up half of our changes, and HEAD stayed broken until we made our commit. Since then the rule is:

  • if a shared file has someone else’s changes in it, we commit our own patch via git apply --cached;
  • before shipping we run the tests on git archive HEAD, not on the working copy.

The suite had 932 tests on October 2 and 2,021 in the October 12 run. A local routine checks production once an hour and messages me if something is wrong.

What’s next

There are three open questions: card payments, Pro economics, and indexing. Czech is already in the code: the engine, A1–A2 decks, a landing page and three guides, but it isn’t live on the site yet.

And users. The weekly report for September 28 – October 4 says: 3 learners, 1 active that week, 1 Pro, 0 payments that week. That’s not a typo. It’s a start.

Sources