MCP — for your Subscribers
Let your subscribers connect their own AI agent, on your login.
Let each of your subscribers connect their own AI agent to your content, tied to their existing login and their plan. Usage comes back to you per subscriber and per tier. Below we run the sign-in once, from the agent to your site and back.
Miso runs the OAuth exchange with the AI agent. Your site provides the login and, on the way back, a signed token that proves who the subscriber is. It is a single round-trip.
Looking for one shared credential for your own team or a single application? See MCP Server for Internal Use. The search and detail tools are the same in both setups — only the sign-in differs.
Which setup do I want?
| Internal use | For your subscribers | |
|---|---|---|
| Who connects | Your team, or one application you run | Each subscriber, in their own agent |
| Credential | One token for the whole app | One access token per subscriber |
| Sign-in | None. You hold the token | Your existing login |
| Usage reports | Per app | Per subscriber and tier |
| Your build | Paste a URL | A login hand-off, described below |
| The address | A Miso URL with your key in it | Your own domain, with an install page |
Where your subscribers connect
Your subscribers do not paste a Miso URL or hold a key. They connect to a host that carries your name, and sign in there:
https://mcp.your-site.com/mcp
That host also serves an install page, a one-command plugin, and a skill that teaches the assistant how to use your content. All of it comes with the host. See Your MCP Host.
The round-trip
What your site needs
You do not need to build an identity provider. If you have a login and can sign a token, you have the pieces. Three things:
1. A sign-in page Miso can redirect to. Miso sends the subscriber to your
login with two query parameters — a state and the callback URL to return
to. The subscriber signs in with their existing account. You confirm that their
plan includes MCP.
2. A redirect back with a signed assertion. Send the subscriber to the
callback carrying a short-lived JWT. Sign it with your Miso secret key
(HS256). That shared secret is how Miso knows the assertion came from you.
3. The right claims in that assertion.
| Claim | What it is |
|---|---|
sub |
A stable subscriber id. Who the access is for. |
access_exp |
How long MCP access stays valid. |
state |
Echo the state Miso sent you. This blocks CSRF. |
aud |
The audience: https://api.askmiso.com. |
exp |
The lifetime of this assertion. Keep it under 5 minutes. |
tier |
Optional. The plan tier, to segment your usage reports. |
What your sign-in page receives
GET https://your-site.com/login
?state=Yk3f...opaque
&callback=https://api.askmiso.com/v1/ask/oauth/callback
Signing the assertion
After the subscriber signs in, and after you confirm their entitlement, sign a short-lived assertion and redirect them back.
import time, jwt # pip install pyjwt
from urllib.parse import urlencode
def redirect_back(state, callback, subscriber_id, tier):
now = int(time.time())
assertion = jwt.encode(
{
"sub": subscriber_id, # stable subscriber id
"aud": "https://api.askmiso.com",
"state": state, # echo Miso's state
"exp": now + 120, # keep this short
"access_exp": now + 30 * 24 * 3600,
"tier": tier, # optional, for reports
},
MISO_SECRET_API_KEY, # your Miso secret key
algorithm="HS256",
)
params = {"state": state, "assertion": assertion}
return redirect(f"{callback}?{urlencode(params)}")
import jwt from "jsonwebtoken"; // npm i jsonwebtoken
function redirectBack(res, state, callback, subscriberId, tier) {
const now = Math.floor(Date.now() / 1000);
const assertion = jwt.sign(
{
sub: subscriberId, // stable subscriber id
aud: "https://api.askmiso.com",
state, // echo Miso's state
exp: now + 120, // keep this short
access_exp: now + 30 * 24 * 3600,
tier, // optional, for reports
},
MISO_SECRET_API_KEY, // your Miso secret key
{ algorithm: "HS256" }
);
const params = new URLSearchParams({ state, assertion });
return res.redirect(`${callback}?${params}`);
}
<?php
use Firebase\JWT\JWT; // composer require firebase/php-jwt
function redirect_back($state, $callback, $subscriber_id, $tier) {
$now = time();
$assertion = JWT::encode(
[
'sub' => $subscriber_id, // stable subscriber id
'aud' => 'https://api.askmiso.com',
'state' => $state, // echo Miso's state
'exp' => $now + 120, // keep this short
'access_exp' => $now + 30 * 24 * 3600,
'tier' => $tier, // optional, for reports
],
MISO_SECRET_API_KEY, // your Miso secret key
'HS256'
);
$q = http_build_query([
'state' => $state,
'assertion' => $assertion,
]);
header("Location: {$callback}?{$q}");
exit;
}
require "jwt" # gem install jwt
def redirect_back(state, callback, subscriber_id, tier)
now = Time.now.to_i
assertion = JWT.encode(
{
sub: subscriber_id, # stable subscriber id
aud: "https://api.askmiso.com",
state: state, # echo Miso's state
exp: now + 120, # keep this short
access_exp: now + 30 * 24 * 3600,
tier: tier # optional, for reports
},
MISO_SECRET_API_KEY, # your Miso secret key
"HS256"
)
query = URI.encode_www_form(state: state, assertion: assertion)
redirect_to "#{callback}?#{query}"
end
That is the whole integration on your side. Miso handles discovery, PKCE, and the token exchange with the agent.
Who does what
| Step | Your site | Miso |
|---|---|---|
| Start | — | Receives the agent and begins OAuth. |
| Sign-in | Login, and enable MCP for the plan. | Redirects the subscriber to you. |
| Hand-back | Redirect back with a signed JWT. | Verifies the JWT. |
| Token | — | Issues the access token to the agent. |
| Reporting | Receives usage reports. | Attributes usage from your claims. |
Availability. Miso sets up subscriber sign-in with you. It needs a short working session with your engineers to agree the login URL, the signing key, and how you map a signed-in user to a subscriber id and tier. Most publishers pilot it on a single tier first. Contact your Miso representative.
The tools your subscribers get
Once connected, a subscriber's agent sees two tools. They are the same two the internal setup gets, and they work the same way here.
The search tool
Named for your brand, for example ask_yourbrand.
| Parameter | Type | Required | Notes |
|---|---|---|---|
question |
string | yes | The question to search for. |
context |
string | no | What the subscriber is working on. Miso adds it to the question. |
skill_used |
string | no | The skill or template that made the call. Analytics only. |
author |
string | no | Restrict results to one author. Available when Miso enables it for your app. |
The agent sends a question in the subscriber's own words. Back come ranked passages from your archive:
{
"query": "interest rate cuts",
"results": [
{
"product_id": "art-20260612-rates",
"product_title": "Central bank signals 2026 cuts",
"authors": "A. Reporter",
"offset": 1,
"snippet_preview": "The central bank said it expects two cuts...",
"published_date": "2026-06-12",
"url": "https://example.com/markets/rates",
"relevance_score": 0.87
}
],
"citation_format": "Use markdown links: [product_title](url) by authors"
}
Each result carries what an answer needs to cite you: the headline, the date, and the URL that sends the reader back to your page. There is no parameter for result count, paging or filtering. Miso scopes every search to your catalog on the server side.
The snippet detail tool
Named get_snippet_detail by default, and renamed for your brand on request.
| Parameter | Type | Required | Notes |
|---|---|---|---|
product_id |
string | yes | From a search result. |
offset |
integer | yes | From the same search result. |
skill_used |
string | no | Analytics only. |
It returns the full text of one passage, plus a ready-made markdown link in
citation_format that the agent is told to cite with.
The two tools are a pair, and the order is enforced. The detail tool accepts
only a product_id and offset that a search returned, and a result stays
readable for one hour after the search that found it. An agent therefore
reads your archive one passage at a time, in response to a real question.
See MCP — Internal Use for the full field list and the content protections that apply to both tools.
Next
- Your MCP Host — the address your subscribers connect to, and what it serves them.
- Tools API — run the same tools inside a server you own.
