Ask your agent to build a service that other Pocketcorps can use by chatting — an MCP server over HTTP, shipped with the instructions that install it.
Your Pocketcorp does what its tools let it do. MCP is how you add a tool — and the interesting part is that you add it by chatting, not by writing it yourself. This guide has your agent build an MCP service with FastAPI, serve it over HTTP on your own domain, and — the part most people skip — ship it with copy-paste instructions so any other Pocketcorp can adopt it in one message. The Marketing dashboard on your own server is the reference implementation: it was built by PocketCorp agents using exactly these techniques.
This is a coding job with a verify loop: write the service, run it, call its own tools, fix what breaks. Hermes is terminal-native and saves what worked as a skill, so the second service you build starts from the first one’s lessons.
Copy this prompt and send it to the agent on your Pocketcorp. It sets up everything in this guide and reports back when it’s done. The steps below explain what your agent is doing — and how to check its work.
Build an MCP service on this server that other Pocketcorps can
adopt with one message.
1. Ask me what the service does and who else may use it. Name the
tools after user intent (list_slots, book_slot), never after
database tables — the tool name and description are the entire
interface an agent sees.
2. Stack: FastAPI + fastapi-mcp, mounted at /mcp over streamable
HTTP, SQLite behind it. Set an explicit operation_id on every
endpoint. Write every docstring for an agent reader: what it
returns, and what it returns when there is nothing to return.
3. Auth: Bearer API keys checked in the backend against stored
hashes. Bind the app to 127.0.0.1 — nginx is the only way in.
certbot for HTTPS on the domain I give you.
4. Write the adopter SKILL.md: the exact MCP config block, which
tools write, the failure modes, and a verification call with its
expected result. Keep it copy-paste clean.
5. Prove it: connect a fresh agent session using ONLY the SKILL.md,
call a read tool, call a write tool, show me the changed row —
then undo it and show the row is gone.Start from the job, not the protocol. Tell your agent what an assistant should be able to do, and who else should be able to use it.
Build me an MCP service for our workshop bookings. An assistant should list free slots, book one, and cancel. Other Pocketcorps should be able to connect to it too.
Plan: FastAPI + fastapi-mcp, mounted at /mcp over streamable HTTP, SQLite behind it. Three tools — list_slots, book_slot, cancel_booking — read-only ones separated from the two that write. Bearer API keys so other servers can authenticate. I’ll write the adopter instructions last, once the tools are real.
Name tools after the user’s intent, not your database. list_slots is discoverable; query_availability_table is not. The tool name and its description are the entire interface an agent sees.
The agent builds on fastapi-mcp rather than hand-rolling a protocol server. The endpoints stay ordinary FastAPI — testable with curl, documented at /docs — and the MCP surface is mounted on the same app:
from fastapi import Depends, FastAPI
from fastapi_mcp import FastApiMCP
from .auth import require_principal
app = FastAPI(title="Workshop Bookings")
@app.get("/api/slots", operation_id="list_slots",
summary="List free workshop slots in a date range")
def list_slots(start: str, end: str, principal=Depends(require_principal)):
"""Free slots between two ISO dates. Returns [] when fully booked."""
...
# Mounted on the same app: one process, one port, one certificate.
mcp = FastApiMCP(app, name="workshop-bookings")
mcp.mount_http() # streamable HTTP at /mcpThe prompt has the agent set operation_id explicitly on every endpoint. It becomes the MCP tool name; left out, adopters get FastAPI’s generated list_slots_api_slots_get — ugly, and unstable across refactors.
Every docstring gets written for its real reader: the assistant deciding whether to call the tool. It says what the tool returns — and what it returns when there is nothing to return.
Streamable HTTP is what lets another Pocketcorp reach your service at all — a stdio server only works for a process on the same machine. The agent binds the app to localhost, puts nginx in front, and lets certbot issue the HTTPS certificate:
# a free PocketCorp address for the service
# bookings.<your-server-id>.apps.pocketcorp.agency
sudo certbot --nginx -d bookings.<your-server-id>.apps.pocketcorp.agency
curl -H "Authorization: Bearer pk_test..." \
https://bookings.<your-server-id>.apps.pocketcorp.agency/mcpNever publish the backend port. Bind to 127.0.0.1 and let nginx be the only way in — that is the pattern every service on your Pocketcorp already follows, and it is what keeps the auth gate from being optional.
For authentication, copy what the Marketing dashboard does: a request carrying a Bearer key bypasses the browser session check and is validated in the backend against a stored hash. Browser users get the session; agents get keys; nothing gets in without one of the two.
This is the step that turns a service into something other Pocketcorps can actually use. An MCP service should carry, in its own repo, a block another agent can be handed verbatim. Adoption then costs one message instead of an afternoon.
## Connect to Workshop Bookings
1. Ask the user for their API key (dashboard → API Keys).
2. Add this MCP server to your config:
{
"mcpServers": {
"workshop-bookings": {
"type": "http",
"url": "https://bookings.<server-id>.apps.pocketcorp.agency/mcp",
"headers": { "Authorization": "Bearer <key>" }
}
}
}
3. Verify: call list_slots for the next 7 days. Expect [] or a list of slots.
## Tools
- list_slots(start, end) — free slots. Read-only.
- book_slot(slot_id, name, email) — books. Fails if taken.
- cancel_booking(booking_id) — cancels. Idempotent.The Marketing dashboard on your own server does exactly this — an operating manual for assistants, plus a full tool reference. Point your agent at it as a worked example: it was built this way, by agents, using these techniques.
Do not accept "done". Ask for the round trip: connect a second agent using nothing but the instructions in the repo, call a read tool, call a write tool, and show the row that changed.
Prove it. Connect fresh using only the SKILL.md, book a slot, and show me the database row.
Connected with the config from SKILL.md — no other context. list_slots returned 6 for next week; booked Thu 14:00; row 41 in bookings now shows name, email, created_at. Cancelled it again and the slot came back in list_slots.
That last sentence is the real test. A booking tool that cannot un-book leaves your calendar wrong forever, and it is exactly the case nobody writes a test for.
A service of your own on your own domain, speaking MCP over HTTP, that any Pocketcorp can adopt in a single message — built by chatting, and carrying the instructions for its own installation.