MCP
MCP reference
What the MCP server sends — its name and instructions, the four tools with their exact descriptions and input schemas, what each tool returns, the errors, and what you can set.
Every agent key is its own MCP server. This page shows what that server sends, word for word, so you can see what the model sees.
The examples use a key named energy-outlooks. It reads one folder, Energy outlooks, holding two
public slide decks from the U.S. Energy Information Administration:
IEO2023 and
AEO2023,
processed with Basic. Every response below is a real one. Only long base64 data is cut, marked with
….
Endpoint
Section titled “Endpoint”| URL | https://sergo.example.com/mcp: the console’s address followed by /mcp |
| Transport | Streamable HTTP. Each JSON-RPC request is one POST, and the answer comes back as application/json in the same response |
| Sessions | None. The server keeps no state between requests and sends no Mcp-Session-Id, so every request carries the key |
| Protocol | Negotiated in initialize. Checked with 2025-06-18 |
Request headers:
| Header | |
|---|---|
Authorization: Bearer sgk_s_… |
Required. An agent key. Personal keys do not work with MCP |
X-Sergo-End-User: <name or id> |
Optional. The person your agent is acting for. It is written to the audit log and does not change what the key can read |
Accept: application/json, text/event-stream |
Sent by MCP clients. The server always answers with JSON |
When the key is missing or wrong, the server answers before MCP starts, with an HTTP error and a JSON body instead of a JSON-RPC message:
401 {"code": "no_auth", "message": "No credentials — send a login token or an sgk_ key in the Authorization header"}401 {"code": "bad_key", "message": "Malformed key — the prefix or checksum doesn't match, so check the value wasn't truncated when copied"}401 {"code": "no_auth", "message": "MCP takes an agent key (sgk_s_…) in the Authorization header"}403 {"code": "personal_key", "message": "Personal keys work with the API only — make a key for an agent to use MCP"}The third is the answer to a console login token, and the fourth to a personal key.
Connect an app
Section titled “Connect an app”In Claude Code:
claude mcp add --transport http energy-outlooks https://sergo.example.com/mcp \ --header "Authorization: Bearer <agent key>"Apps that read an mcpServers file, such as Claude Desktop or Cursor, take the same three values:
{ "mcpServers": { "energy-outlooks": { "type": "http", "url": "https://sergo.example.com/mcp", "headers": { "Authorization": "Bearer <agent key>" } } }}The console shows both, with your key filled in, when you create the key. The name in front of the
URL is chosen by the app, not by Sergo. Apps put it in front of each tool name, so Claude Code calls
the first tool mcp__energy-outlooks__search.
What the server says about itself
Section titled “What the server says about itself”The answer to initialize:
{ "jsonrpc": "2.0", "id": 1, "result": { "capabilities": { "tools": { "listChanged": false } }, "instructions": "energy-outlooks — a document store you can search.\nEIA's 2023 energy outlook release decks, uploaded as PowerPoint files: the International Energy Outlook 2023 (IEO2023, world projections to 2050) and the Annual Energy Outlook 2023 (AEO2023, United States projections to 2050)\nUse `search` first; it returns the best-matching excerpts, grouped by document. Use `read_document` with an id from this server's `search` to read more of one document — a page, the pages around an excerpt, or the whole. Use `list_documents` to see what is here without searching, or when a search finds nothing. Use `view_page` to look at a page as a picture when its text is missing or a table, chart or figure matters — it costs more tokens than text.", "protocolVersion": "2025-06-18", "serverInfo": { "description": "EIA's 2023 energy outlook release decks, uploaded as PowerPoint files: the International Energy Outlook 2023 (IEO2023, world projections to 2050) and the Annual Energy Outlook 2023 (AEO2023, United States projections to 2050)", "name": "energy-outlooks", "title": "energy-outlooks", "version": "0.6.0" } }}serverInfo.nameandtitleare the key’s name.serverInfo.descriptionis the key’s description.instructionshas three lines: the key’s name, its description, and a fixed paragraph on the order to use the tools. Apps such as Claude Code put it in the model’s system prompt.- The server offers tools only: no resources and no prompts.
The answer to tools/list, in the order the server sends it. The key’s name, description and folder
names are written into the descriptions, so they differ from key to key.
{ "tools": [ { "name": "search", "description": "Search energy-outlooks: EIA's 2023 energy outlook release decks, uploaded as PowerPoint files: the International Energy Outlook 2023 (IEO2023, world projections to 2050) and the Annual Energy Outlook 2023 (AEO2023, United States projections to 2050). Returns the best-matching excerpts — at most half of them from one document — grouped by document, with the document id, name and folder, and each excerpt's page (and section, in Word files). `pages_estimated: true` on a document means its page numbers are estimates — `read_document` takes them, `view_page` may show other pages. `view_page_may_help: true` on an excerpt means the text of that page may miss a figure, chart or table — `view_page` shows the page. `image_only_pages` lists pages of that document with no text, only a picture, which search cannot find. When the excerpts do not answer, the answer may be on one of those, or on the pages next to an excerpt (`read_document` with `page` and `to_page`).", "inputSchema": { "type": "object", "properties": { "query": { "type": "string", "description": "What to look for — plain words or a question" }, "limit": { "type": "integer", "minimum": 1, "maximum": 20, "default": 10, "description": "How many excerpts to return (at most half of them from one document)" }, "offset": { "type": "integer", "minimum": 0, "maximum": 80, "default": 0, "description": "Skip this many excerpts — the result says the offset of the next ones when there are more" }, "folders": { "type": "array", "items": { "type": "string" }, "description": "Only search these folders, by name: Energy outlooks — or any folder inside them, by its own name" } }, "required": ["query"] } }, { "name": "list_documents", "description": "List the documents in energy-outlooks — newest first, with the id, name, folder, type, page count and the pages to view (figures or tables the text does not carry) of each. Use it to see what is here without searching, or when a search finds nothing. Documents marked not_indexed have no text to search yet; `pages_estimated` means the page count and numbers are estimates.", "inputSchema": { "type": "object", "properties": { "folders": { "type": "array", "items": { "type": "string" }, "description": "Only list these folders, by name: Energy outlooks — or any folder inside them, by its own name" }, "limit": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 }, "offset": { "type": "integer", "minimum": 0, "default": 0, "description": "Skip this many — use `next_offset` from the last result" } } } }, { "name": "read_document", "description": "Read the text of a document from energy-outlooks — use an id from energy-outlooks's `search` or `list_documents`. Returns its name, folder, how many pages it has, and the text: one page when `page` is given, pages `page` to `to_page` when both are given (such as the pages around a search excerpt), otherwise the whole document up to a limit (then it says up to which page it got). `pages_to_view` lists pages whose text may miss a figure, chart or table — use `view_page` on those when they matter.", "inputSchema": { "type": "object", "properties": { "document_id": { "type": "string", "description": "The id from a search result" }, "page": { "type": "integer", "minimum": 1, "description": "One page's text, or the first page with `to_page` — leave out for the whole document" }, "to_page": { "type": "integer", "minimum": 1, "description": "With `page`: read through this page too" } }, "required": ["document_id"] } }, { "name": "view_page", "description": "Look at one page of a document from energy-outlooks as a picture (or a one-page PDF) — for pages where `read_document` gives little or no text, or when a table, chart or figure matters. Costs more tokens than text, so read the text first. Only for PDFs and files with a PDF copy.", "inputSchema": { "type": "object", "properties": { "document_id": { "type": "string", "description": "The id from a search result or list_documents" }, "page": { "type": "integer", "minimum": 1, "description": "The page to look at — usually one marked `view_page_may_help`, or in `image_only_pages` or `pages_to_view`" }, "format": { "type": "string", "enum": ["image", "pdf"], "default": "image", "description": "image (PNG) works everywhere; pdf keeps the text layer" } }, "required": ["document_id", "page"] } } ]}When a key reads single files and no folders, the folders description of both tools becomes
This key reads single files, not folders — leave this out. Up to 20 folder names are listed; past
that the list ends with ….
Pages to view
Section titled “Pages to view”When Sergo processes a file it marks each page whose text may miss something, such as a chart, a figure or a table. Basic marks pages by simple rules: little text, a large picture, or many drawn lines. For a PowerPoint file it looks at the shapes on the slide instead: pictures, charts, SmartArt and diagrams drawn with shapes. Standard (AI) asks the transcribing model. The marks appear in these places:
view_page_may_help: trueon a search excerpt from such a page.image_only_pageson a search result: the document’s marked pages that have no text at all, only a picture. Search cannot find those pages, so this is the only hint in the result that they exist.pages_to_viewfromlist_documentsandread_document: all marked pages of the document.- A
view_page_may_helpsentence on aread_documentresult for one such page, and a note in the page heading when you read a range of pages.
See Processing for the presets.
Estimated pages
Section titled “Estimated pages”Word and text files have no pages of their own. Sergo gives each chunk an estimated page, and for a
Word file read by Basic it makes a PDF copy in the background. Once the copy exists, the chunks
take its pages, the same pages view_page shows. Until then:
pages_estimated: trueon a search result, alist_documentsitem or aread_documentresult means the page numbers are estimates.read_documenttakes them like any other page number.view_pageanswers that the PDF copy is still being made. Text files get no PDF copy, so their pages stay estimates andview_pagehas nothing to show.
search
Section titled “search”| Argument | Type | Default | |
|---|---|---|---|
query |
string | required | Words or a question |
limit |
integer | 10 | Excerpts to return, 1 to 20. At most half of them, rounded up, come from one document |
offset |
integer | 0 | Excerpts to skip, 0 to 80, for the next ones. Keep the same query, limit and folders |
folders |
string array | all | Folder names, searched with the folders inside them. A path also works, such as Energy outlooks/Basic or a folder value from a result |
The result is one text block holding a JSON array, one item per document. Each document carries
its best-matching excerpts, best first, and the documents come in the order of their best excerpt.
limit counts excerpts, not documents, and one document gets at most half of them, rounded up: two
of four here, five of the default ten, so one long document cannot crowd out the others. This is the whole JSON-RPC response for
{"query": "electric vehicle sales in China", "limit": 4}:
{"jsonrpc": "2.0", "id": 3, "result": {"content": [{"text": "[{\"document_id\":\"xM5gW8NZ\",\"document\":\"IEO2023_Release_Presentation.pptx\",\"folder\":\"Ava Bennett's documents/Energy outlooks/Basic\",\"hits\":[{\"page\":18,\"view_page_may_help\":true,\"excerpt\":\"Electric vehicle sales grow due to policy incentives, \\nbattery costs, efficiency standards, and electricity \\nprices\\n18 IEO2023 Release, CSIS \\n October 11, 2023\"},{\"page\":21,\"view_page_may_help\":true,\"excerpt\":\"By 2050, global coal\\nfired and liquid fuelfired \\nelectricity generating capacity decrease in most \\nmodeled cases\\n21 IEO2023 Release, CSIS \\n October 11, 2023\"}]},{\"document_id\":\"dArXTFR7\",\"document\":\"AEO2023_Release_Presentation.pptx\",\"folder\":\"Ava Bennett's documents/Energy outlooks/Basic\",\"hits\":[{\"page\":20,\"excerpt\":\"IRA incentives speed growth in sales of electric vehicles\\n20 AEO2023 Release, RFF\\nMarch 16, 2023\\nData source: U.S. Energy Information Administration, Annual Energy Outlook 2023 (AEO2023)\\nNote: *Includes battery electric and plug-in hybrid electric vehicles. IRA=Inflation Reduction Act\\n0%\\n5%\\n10%\\n15%\\n20%\\nNo IRA\\nLow Uptake\\nHigh Uptake\\nReference\\nMarket share of electric light-duty vehicles*\\npercentage\\n 2022\\nhistory projections\"},{\"page\":19,\"excerpt\":\"gy y \\nmarket share increase through 2050 due to rising CAFE \\nStandards and other incentives\\n19\\n20\\n25\\n30\\n35\\n40\\n45\\nLight-duty vehicle average fuel economy\\nmiles per gallon\\n 2022\\nhistory projections\\nHigh Oil \\nPrice\\nReference\\nLow Oil \\nPrice\\nData source: U.S. Energy Information Administration, Annual Energy Outlook 2023 (AEO2023)\\nNote: *Includes battery electric and plug-in hybrid electric vehicles. Shaded regions represent maximum and minimum values \\nfor each projection year across the AEO2023 Reference case and side cases.\\n0%\\n10%\\n20%\\n30%\\n40%\\nMarket share of electric light-duty vehicles*\\npercentage of sales\\n 2022\\nhistory projections\\nHigh Oil \\nPrice\\nReference\\nLow Oil \\nAEO2023 Release, RFF \\nMarch 16, 2023\"}]}]", "type": "text"}, {"text": "More excerpts past these: search again with offset 4.", "type": "text"}], "isError": false}}The server sends the JSON without spaces to save the model tokens. The same text, laid out, with the two long excerpts cut short here:
[ { "document_id": "xM5gW8NZ", "document": "IEO2023_Release_Presentation.pptx", "folder": "Ava Bennett's documents/Energy outlooks/Basic", "hits": [ { "page": 18, "view_page_may_help": true, "excerpt": "Electric vehicle sales grow due to policy incentives, \nbattery costs, efficiency standards, and electricity \nprices\n18 IEO2023 Release, CSIS \n October 11, 2023" }, { "page": 21, "view_page_may_help": true, "excerpt": "By 2050, global coal\nfired and liquid fuelfired \nelectricity generating capacity decrease in most \nmodeled cases\n21 IEO2023 Release, CSIS \n October 11, 2023" } ] }, { "document_id": "dArXTFR7", "document": "AEO2023_Release_Presentation.pptx", "folder": "Ava Bennett's documents/Energy outlooks/Basic", "hits": [ { "page": 20, "excerpt": "IRA incentives speed growth in sales of electric vehicles\n…" }, { "page": 19, "excerpt": "gy y \nmarket share increase through 2050 due to rising CAFE \n…" } ] }]| Field | |
|---|---|
document_id |
Use it with the other three tools |
document |
File name |
folder |
Path of the folder holding the file, starting with the owner’s name, such as Ava Bennett's documents/… |
image_only_pages |
Marked pages of the document with no text, only a picture. Search cannot find them. Left out when there are none |
hits |
The document’s matching excerpts, best first |
page |
Page of the excerpt. Left out for files without pages |
section |
The heading above the excerpt, for files without pages, such as Word files read with Basic |
view_page_may_help |
true when the excerpt’s page is marked: its text may miss a figure, chart or table. Left out otherwise |
excerpt |
The matching text. Usually a whole page; a long page is split into a few excerpts |
There are no scores. They only rank the excerpts of one search, and the best one scores near the top even when the documents do not hold the answer.
When there are more excerpts, a second text block follows the array, as in the response above:
More excerpts past these: search again with offset 4. The same call with that offset gives the
next ones in the same order, each document still capped at half of limit. How deep a search goes
is set by the install’s search settings, usually a few dozen passages, so the line stops before
every match is shown.
Other answers, each a single text block:
Nothing matched. (isError: false)Nothing past this point. (isError: false)Give a query to search for. (isError: true)No folder named 'IEO2023' here. Use one of: Basic (isError: true)The last one lists the folders the key reads, followed by — or a folder inside them: … when they
have subfolders. A key that reads only single files answers
No folder named 'IEO2023' here — this key reads single files, not folders. Leave folders out.
list_documents
Section titled “list_documents”| Argument | Type | Default | |
|---|---|---|---|
folders |
string array | all | Same as in search. Files the key reads on their own, outside any folder, are left out when you narrow by folder |
limit |
integer | 50 | 1 to 100 |
offset |
integer | 0 | Use next_offset from the last result |
Documents come newest first. The result for {}, laid out:
{ "total": 2, "items": [ { "document_id": "dArXTFR7", "document": "AEO2023_Release_Presentation.pptx", "folder": "Ava Bennett's documents/Energy outlooks/Basic", "type": "pptx", "pages": 25, "pages_to_view": [1, 3, 5, 14, 24, 25], "uploaded": "2026-10-24" }, { "document_id": "xM5gW8NZ", "document": "IEO2023_Release_Presentation.pptx", "folder": "Ava Bennett's documents/Energy outlooks/Basic", "type": "pptx", "pages": 27, "pages_to_view": [1, 3, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 21, 22, 24, 25, 27], "uploaded": "2026-10-24" } ]}| Field | |
|---|---|
total |
Documents in the scope, or in the folders you asked for |
next_offset |
Present when there are more. Pass it as offset |
type |
File type, such as pdf, docx or pptx |
pages |
Page count, when Sergo knows it |
uploaded |
Date of upload |
status |
processing when the document will show up in search soon, or not_indexed when it has no text to search until someone processes it. Left out for searchable documents |
With nothing to list, the answer is No documents here., or Nothing past this point. when
offset is past the end.
read_document
Section titled “read_document”| Argument | Type | Default | |
|---|---|---|---|
document_id |
string | required | From search or list_documents |
page |
integer | none | One page, or the first page of a range. Leave it out for the whole document |
to_page |
integer | none | With page, read through this page too |
The result for {"document_id": "xM5gW8NZ", "page": 18}, laid out:
{ "document": "IEO2023_Release_Presentation.pptx", "folder": "Ava Bennett's documents/Energy outlooks/Basic", "page": 18, "pages": 27, "pages_to_view": [1, 3, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 21, 22, 24, 25, 27], "view_page_may_help": "This page's text may miss a figure, chart or table — `view_page` shows it", "text": "Electric vehicle sales grow due to policy incentives, \nbattery costs, efficiency standards, and electricity \nprices\n18 IEO2023 Release, CSIS \n October 11, 2023"}Without page, the result has no page and no view_page_may_help, and text holds the whole
document. Whole pages go in until the text reaches 24,000 characters. When some pages do not fit,
two more fields say so:
{ "pages_read": "1-17", "more": "Pages 18-30 not included — ask for a page to read on"}The 27 slides of IEO2023 come to about 8,000 characters, so the whole deck comes back in one call.
With page and to_page, text holds those pages, each under a heading such as --- page 17 ---.
Use it for the pages around a search excerpt. A marked page says so in its heading:
(view_page may help — the text may miss a figure, chart or table), or
(no text, only a picture — view_page shows it) when the page has no text. The result for
{"document_id": "xM5gW8NZ", "page": 17, "to_page": 18}, laid out:
{ "document": "IEO2023_Release_Presentation.pptx", "folder": "Ava Bennett's documents/Energy outlooks/Basic", "pages": 27, "pages_read": "17-18", "pages_to_view": [1, 3, 7, 8, 9, 10, 11, 14, 15, 16, 17, 18, 19, 21, 22, 24, 25, 27], "text": "--- page 17 (view_page may help — the text may miss a figure, chart or table) ---\nIEO2023 Release, CSIS 17\nOctober 112023\nIncreasing passenger demand drives global \ntransportation consumption; Rising income enables \ntravelers to shift from inexpensive, more efficient modes \nto more convenient, less efficient modes\n\n--- page 18 (view_page may help — the text may miss a figure, chart or table) ---\nElectric vehicle sales grow due to policy incentives, \nbattery costs, efficiency standards, and electricity \nprices\n18 IEO2023 Release, CSIS \n October 11, 2023"}pages_read says which pages came back. A range stops at the last page of the document, and at
24,000 characters like the whole document; then more names the pages left out, such as
"Pages 31-40 not included — ask for them".
Other answers:
(nothing on this page) as "text" — a page without text, such as a scan read with Basic(no text in this document) as "text"This document has 27 pages isError: true — page past the end`to_page` must not be before `page` isError: trueNot found, or not yours to see — the two are deliberately indistinguishable isError: trueview_page
Section titled “view_page”| Argument | Type | Default | |
|---|---|---|---|
document_id |
string | required | |
page |
integer | required | |
format |
image or pdf |
image |
image is a PNG. pdf is that page alone as a PDF, with its text layer |
The result has two blocks: a caption, then the page. For {"document_id": "xM5gW8NZ", "page": 18}:
{ "content": [ { "type": "text", "text": "IEO2023_Release_Presentation.pptx — page 18 of 27" }, { "type": "image", "mimeType": "image/png", "data": "iVBORw0KGgoAAAANSUhEUgAABEwAAAJrCAIAAAB1GpFZ…" } ], "isError": false}With "format": "pdf", the second block is an embedded resource:
{ "type": "resource", "resource": { "uri": "sergo://documents/xM5gW8NZ/pages/18.pdf", "mimeType": "application/pdf", "blob": "JVBERi0xLjcNCiWhs8XXDQoxIDAgb2JqDQo8PC9QYWdlcyAyIDAgUiAvVHlw…" }}- The picture is drawn at 110 dpi, with the longer side at most 1,568 pixels. A slide comes out 1,100 × 619 pixels and costs a model about 1,000 input tokens.
- PDFs are drawn as they are. Office files are drawn from their PDF copy, so for a slide deck the page number is the slide number.
- A one-page PDF can be much larger than the picture, because it carries the fonts and images of
the page. For slide 18 above, the response was 189 KB with
imageand 1.65 MB withpdf.
Other answers:
This document has 27 pages isError: trueNo page view for this file — it was read without a PDF copy. A person can make one in the console (Make a PDF copy). isError: trueThe second comes for files that have no PDF copy, such as a Word file read with Basic, or a text file.
How apps pass the page to the model
Section titled “How apps pass the page to the model”The MCP server returns the blocks. The app running the agent decides how they reach the model. Checked on 2026-10-24:
| App | Picture | One-page PDF |
|---|---|---|
| Claude Code | Passed to the model | Saved to a file. The model opens it with Read |
Anthropic API, LangChain ChatAnthropic |
Inside the tool result | Inside the tool result |
| OpenAI-compatible chat APIs, picture in a user message after the tool message | Read | Depends on the provider and model |
LangChain ChatOpenAI, picture inside the tool message |
Dropped without an error | Dropped without an error |
| OpenAI Agents SDK | Passed as a picture | Sent as base64 text, tens of thousands of tokens |
Pictures work almost everywhere, which is why image is the default.
Errors
Section titled “Errors”A tool that fails still answers with a result, with isError: true and one sentence. The model can
read it and try again: a wrong folder name comes with the names it can use, and a page past the end
comes with the page count.
{"jsonrpc": "2.0", "id": 16, "result": {"content": [{"text": "No tool named 'summarize'.", "type": "text"}], "isError": true}}Only a missing or wrong key fails at the HTTP level. See Endpoint.
What you can set
Section titled “What you can set”On the key, under Agent keys in the console:
| Setting | What it changes |
|---|---|
| Name | serverInfo.name, the first line of instructions, and every tool description. Use 2 to 32 lowercase letters, digits and dashes, starting with a letter. A new name takes effect on the app’s next connection |
| Description | serverInfo.description, the second line of instructions, and the search description. Say what the documents are and when to use them; the model reads it to decide when to call this server |
| Can read | Which folders and files the server can see. The folder names appear in the folders descriptions |
| Key value | Roll gives the key a new value and keeps the old one working until the time you choose: now, 1 hour, 24 hours or 7 days. The name, description and access stay the same |
On each document, the processing preset decides which pages are pages to view. See Processing.
On each request, X-Sergo-End-User names the person the agent is acting for. It appears in the
audit log.
Fixed by the server:
search results |
10 by default, at most 20. offset up to 80 |
list_documents page |
50 by default, at most 100 |
read_document without page |
Whole pages up to 24,000 characters |
view_page picture |
110 dpi, longer side at most 1,568 pixels |
| Folder names in tool descriptions | The first 20 |
Each call is written to the audit log under the key’s masked value, with the X-Sergo-End-User
value if sent:
| Call | Audit entry |
|---|---|
search |
mcp search, with the query and the number of results, and where they start when offset is given |
list_documents |
mcp listing, with the folders asked for or “whole scope” and the number of documents |
read_document |
mcp text read, with the file and the page, “all pages”, or “pages 1-k of N” |
view_page |
mcp page viewed, with the file, the page and the format |