Tools API
You host the MCP server. Miso does the searching.
This page is for a team that wants to run its own MCP server, and wants Miso's agentic search inside it. You keep the server, the transport, the tool names and the authentication. Miso answers the two calls underneath: one that lists the tools, one that runs a search and returns passages worth citing.
What the search does: a question arrives in a reader's own words, and the answer comes back as ranked passages from your archive, each with its title, date and URL to cite.
Below we make both calls, then put them inside a working MCP server.
Prefer Miso to run the server too? Your MCP Host gives you an address on your own domain, with an install page and sign-in built in.
The two calls
| Call | What it gives you |
|---|---|
GET /v1/ask/mcp/tools |
Every tool your app exposes, with a JSON Schema for its arguments. |
POST /v1/ask/mcp/tools/{name} |
The result of running one tool. |
Both live on https://api.askmiso.com. Both take your Secret API Key, in
either header:
X-API-Key: YOUR_SECRET_API_KEY
Authorization: Bearer YOUR_SECRET_API_KEY
Without a key the reply is 401. The key is a server credential, so these
calls belong on your back end.
List the tools
curl -s https://api.askmiso.com/v1/ask/mcp/tools \
-H "X-API-Key: YOUR_SECRET_API_KEY"
{
"tools": [
{
"name": "ask_your_site",
"description": "Search the Your Site archive — news, analysis and reference.",
"input_schema": {
"type": "object",
"properties": { "question": { "type": "string" } },
"required": ["question"]
}
},
{
"name": "get_your_site_article",
"description": "Get the full text of a specific snippet returned by ask_your_site.",
"input_schema": {
"type": "object",
"properties": {
"product_id": { "type": "string" },
"offset": { "type": "integer" }
},
"required": ["product_id", "offset"]
}
}
],
"version": "1.0.0"
}
Two tools come back. A search tool, named for your brand, and a detail
tool that returns the full text of one result. The names and descriptions
are the ones Miso set up with you, so ask_your_site above stands for your
own tool name.
input_schema is JSON Schema. Hand it to your MCP server as the tool's schema
rather than retyping it, and a change Miso makes reaches your agent on your
next start.
Run a tool
Arguments go in an arguments object:
curl -s https://api.askmiso.com/v1/ask/mcp/tools/ask_your_site \
-H "X-API-Key: YOUR_SECRET_API_KEY" \
-H "Content-Type: application/json" \
-d '{"arguments": {"question": "What happened at the 2012 Olympics opening ceremony?"}}'
{
"success": true,
"result": "{\"query\": \"...\", \"results\": [ ... ], \"citation_format\": \"...\"}"
}
result is a string. It holds JSON, so parse it once more before you read
it. Returning it as a string is what an MCP client expects to receive, so a
server that passes it straight through needs no parsing at all.
Inside, a search result carries the fields your agent cites from:
| Field | What it is |
|---|---|
product_id |
The article. Pass it back to the detail tool. |
offset |
Which passage of that article matched. The detail tool needs it too. |
product_title |
The headline, for the citation. |
url |
Where the citation points. |
published_date |
The date, for recency questions. |
snippet_preview |
The passage that matched, to show or to judge relevance. |
relevance_score |
How well it matched, between 0 and 1. |
The detail tool takes product_id and offset from a result and returns the
same fields plus content, the full text.
Wrap them in your server
The whole integration is one function that forwards a call, plus one tool declaration for each Miso tool. In the following server, we expose both tools under our own names:
import os, requests
from mcp.server.mcpserver import MCPServer
MISO_BASE = "https://api.askmiso.com/v1/ask/mcp/tools"
HEADERS = {"X-API-Key": os.environ["MISO_SECRET_API_KEY"]}
mcp = MCPServer("your-site")
def call_miso(name, arguments):
response = requests.post(
f"{MISO_BASE}/{name}", headers=HEADERS, json={"arguments": arguments}, timeout=60
)
response.raise_for_status()
body = response.json()
if not body["success"]:
raise RuntimeError(body["error"])
return body["result"]
@mcp.tool()
def search(question: str) -> str:
"""Search our archive. Returns snippets with titles, dates and URLs."""
return call_miso("ask_your_site", {"question": question})
@mcp.tool()
def get_article(product_id: str, offset: int) -> str:
"""Return the full text of one result from search."""
return call_miso("get_your_site_article", {"product_id": product_id, "offset": offset})
if __name__ == "__main__":
mcp.run()
Your agent now sees search and get_article on your server. The tools keep
Miso's behaviour, and the name, the description and the transport are yours.
Your key stays on your server, and your subscribers never hold a Miso credential. Access is yours to control: put your own API key or your own sign-in in front of this server, and it decides who gets in.
Narrow a connection to content types
Add type= to either call, and the tools answer only from those content
types. The value is a comma-separated list, matched exactly as your content is
indexed:
curl -s "https://api.askmiso.com/v1/ask/mcp/tools?type=COURSE,SERVICE" \
-H "X-API-Key: YOUR_SECRET_API_KEY"
Send the same parameter on the call that runs a tool. A listing narrowed this way also says so in the tool description, so the agent knows what it is searching. This is how one app serves two servers: a wide one for your own team, and a narrow one for a customer-facing agent.
When something fails
| What you get | What happened |
|---|---|
401 |
No key, or a key that is not this app's secret key. |
404 with Tool not found |
The tool name is not one from the listing. |
200 with "success": false |
The tool ran and failed. error says why. |
The third one is the one to handle deliberately. A missing required argument
arrives here, with success: false and a message naming the argument. Raise
it as a tool error in your server so the agent can correct itself and try
again.
Next
- Your MCP Host — a Miso-run server on your own domain.
- MCP — Internal Use — connect a client with no server of your own.
- MCP — for your Subscribers — per-subscriber sign-in.
