Product engineering

Your AI Assistant Can Book a Call With Me: llms.txt, MCP, and a Link That Cannot Book Anything

Most websites are built for humans and scraped by bots. Mine also talks to agents on purpose. Here is the whole design: three ways in, one confirmation email, and a URL that is safe to hand to a stranger's AI.

Author

Published

Updated

Length

11 min · 1,500 words

Key takeaways

  • /llms.txt is the front door for agents: who I am, what is live, and exactly how to request a call.
  • Three paths in: an MCP tool (request_call), a REST POST to /api/v1/agent/bookings, or a prefilled /book link.
  • In the prefilled link everything after # stays in the browser and is never sent to the server.
  • Opening a URL never books anything. A request with an email is held until the person clicks Confirm in an email.
  • Live capacity (slots, weekly hours, next start date) is served from an ops database, not hard-coded into pages.
  • Calls run on weekdays, 09:30 to 13:30 IST.

Someone asks an AI assistant, "find me a freelance Next.js developer and set up a call." The assistant finds my site. What happens next is usually a dead end: it summarises a landing page, then tells the human to go figure out the contact form. I decided that dead end was a bug, so I fixed it. The fix is three small pieces and one rule.

The front door: llms.txt

Websites have `robots.txt` for crawlers and `sitemap.xml` for search engines. Agents need something different: a short, plain-text briefing they can read in one fetch. That is /llms.txt. It states who I am, links every case study and blog post with a one-line description, and then does the part most sites skip: it tells the agent exactly what it is allowed to do and how.

It is generated from the same data as the rest of the site, so the post list and case list cannot drift out of date. Publish a new article and the agent-facing index updates with it.

Why capacity is not on the page

Whether I have a free project slot this month is a fact that changes weekly. Baking it into a statically built page means every visitor and every cached copy in an AI's memory is eventually wrong. So the pages describe me, and live facts come from a small ops database exposed three ways: a REST snapshot at `/api/v1/agent/ops`, an OpenAPI document at `/openapi.json`, and an MCP endpoint at `/api/mcp`.

Three ways an agent can reach me
PathBest forHow it works
MCP connectorAssistants that support toolsCall request_call with an email or phone. Name, timezone, preferred times, and project are optional.
REST APIScripts and custom agentsPOST JSON with email or phone to /api/v1/agent/bookings.
Prefilled linkAny assistant that can only write textGive the human a /book#... URL. Their browser does the rest.

The MCP server is stateless Streamable HTTP and exposes tools such as `get_ops_snapshot`, `get_capacity`, `list_positions`, `list_engagements`, `get_availability`, and `request_call`. An agent can answer "is he free in January?" from data, not from a guess.

The third path is my favourite because it works with the dumbest possible assistant. A chat model that can only output text can still output a URL:

https://vishu.app/book#name=Alex&email=alex%40gmail.com&times=Tue%2010%3A00%20IST&project=Delivery%20app

Keys are `name`, `email`, `phone`, `times`, and `project`. All are optional, URL-encoded, and placed after the `#`. The human clicks, the form is already filled, and with an email present the request goes out immediately.

Why the # matters

Everything after `#` is the URL fragment. Browsers keep it client-side and do not include it in the HTTP request. So the name, email, and project description an assistant packs into the link never appear in my server access logs, a CDN log, or a referrer header. The page's own JavaScript reads it locally. For a link that carries a stranger's contact details, that is the right default.

The rule: opening a URL never books anything

Here is the part that took the most thought. Link previews, chat apps, security scanners, and AI browsing tools all open URLs on a person's behalf, sometimes several times. If opening a link could finalise a booking, a scanner would book calls for people who never asked. So I split the flow in two:

  1. Request. Opening the link (or calling the API or MCP tool) with an email records the request and sends a confirmation email to that address.
  2. Confirm. The call is booked only when the person clicks Confirm in that email.

This is double opt-in, the same pattern newsletters use, applied to a calendar. It means an assistant can act confidently for someone else ("book this for my friend") without ever being able to commit them. A phone-only link works differently: it opens the form with the number filled in and the person submits it themselves. Calls are held on weekdays, 09:30 to 13:30 IST.

Why bother

  • Discovery is moving. A growing share of "who should I hire" starts in an assistant, not a search box. If the assistant cannot act on my site, it recommends someone it can act on.
  • It is cheap. One text file, one route handler, one MCP endpoint. The data already existed.
  • It is honest. Accurate, current facts in a format agents can cite beat hoping a model remembers a stale scrape.
  • It is a demo. Anyone evaluating whether I can build agent-ready products can click the link and watch it work.

Steal this pattern

  1. Write a `/llms.txt` that says who you are and, explicitly, what an agent may do.
  2. Serve volatile facts from an endpoint, not from static pages.
  3. Offer one structured path (MCP or REST) and one dumb path (a prefilled link).
  4. Put user data in the URL fragment, not the query string.
  5. Never let a GET request commit anything. Make a human confirm out of band.

Want to try it? Read llms.txt, or just book a call. If you are building something similar and want it done properly, that is the kind of work in my case studies, and the same thinking drives natural-language database tools: give the model rails, not a blank check.

Frequently asked questions

Can an AI assistant book a call with Vishu Pratap?

It can request one. With the MCP connector at https://vishu.app/api/mcp it calls request_call; over HTTP it POSTs to https://vishu.app/api/v1/agent/bookings; without either it hands the person a prefilled link such as https://vishu.app/book#name=Alex&email=alex%40gmail.com. The call is only booked when the person clicks Confirm in the email sent to their address.

What is llms.txt on vishu.app?

It is a plain-text page at https://vishu.app/llms.txt written for AI agents. It lists who Vishu is, his case studies and posts, the live-availability endpoints, and step-by-step booking instructions.

Is the data in the prefilled booking link sent to the server?

No. Everything after the # sign is the URL fragment. Browsers do not send it to the server in the HTTP request, so the name, email, and project text stay in the person's browser until they submit.

Can opening the link book a call by accident?

No. Opening a URL never books anything. With an email in the link, the request is sent and a confirmation email goes to that address; the call is booked only when the person clicks Confirm there.
AI agentsllms.txtMCPOpenAPIAgent experienceBooking
©2025Vishu Pratap · Software Developer