What is Pilot MCP?
Pilot MCP is a remote Model Context Protocol server that exposes a focused set of read-only tools from Senpilot, the AI-native operating system for utilities. It lets an MCP-compatible client (Claude, Claude Code, Cursor, and others) work with your utility's regulatory corpus and the dataset-extraction jobs you've already run inside Senpilot.
It's built for regulatory analysts, rate-case teams, and utility staff who want to bring Senpilot's regulatory agent into the same chat surface they're already using, without copy-pasting filings around or leaving their tool of choice.
Connector details
- Server URL
https://api-app-production-na-ne2.senpilot.com/pilot-mcp- Transport
- Streamable HTTP
- Authentication
- OAuth 2.0 with PKCE (S256). A Senpilot account is required.
- Capabilities
- Read-only. No tool writes to Senpilot or to any utility system.
- Tools
ask_pilot_reg,get_pilot_reg_results,list_completed_dataset_extractions,get_dataset_extraction_rows
Setup
You only need a Senpilot account.
Add as a custom connector
Add Pilot to your client as a custom MCP server:
- Open your client's "Add connector" (or "Custom MCP server") flow.
- Paste the server URL:
https://api-app-production-na-ne2.senpilot.com/pilot-mcp. - Choose Streamable HTTP as the transport, if asked.
- The client will redirect you to Senpilot to sign in via OAuth and approve access.
- After approval, the four tools below appear in the client's tool list.
Tools
All tools are read-only. Each runs against the authenticated user's own utility data. Pilot MCP never exposes another tenant's data.
ask_pilot_reg
Read-onlyAsk Pilot a regulatory question
Ask Pilot a question grounded in your utility's regulatory corpus and the public regulatory record. Answers come back with structured citations tying each claim to a specific filing, decision, or page. Pass a threadId returned from a previous call to continue the same conversation, or omit it to start a new one. Longer questions may take a moment to complete — when that happens, the client transparently polls get_pilot_reg_results until the answer is ready.
Inputs
questionrequiredThe regulatory question to ask, in natural language.threadIdoptionalThread UUID returned by a previous call. Omit to start a new conversation.
Example prompts
01“Summarize the OEB's most recent decisions on storm-cost deferral account treatment, and list the precedents Pilot cites.”
Expected: A concise summary with inline citation markers, plus a structured list of regulatory filings and decisions backing each claim.
02“What rate-case precedents exist in Ontario for capital-cost recovery on AMI deployments over the last five years?”
Expected: An evidence-backed answer with cited decisions, applications, and ruling excerpts, usable as a starting point for an IR response or business case.
03“Continue thread <threadId>: which other Canadian jurisdictions have approved similar formula-rate-plan mechanisms, and what conditions did they attach?”
Expected: A follow-up that builds on the prior conversation, returning the same
threadIdand a fresh set of citations across additional jurisdictions. If a previous turn on the same thread is still running, the new question is queued and processed as the next turn.
get_pilot_reg_results
Read-onlyCheck on a Pilot regulatory question in progress
Companion to ask_pilot_reg for questions that take more than a moment to answer. When ask_pilot_reg signals it's still working, the MCP client uses this tool to check back until the answer is ready, then returns the same answer and citations it would have on a fast call. You generally don't need to think about this — the client handles it automatically.
Inputs
threadIdrequiredThread UUID returned by an earlierask_pilot_regcall.
Example prompts
01“Pilot is taking a while on threadId <threadId> — keep checking until the answer is ready, then summarize it for me.”
Expected: The client checks back every few seconds until Pilot finishes, then returns the final answer with its citations — the same shape a fast call would have produced.
02“On threadId <threadId>, if Pilot's background run failed, tell me what happened instead of retrying.”
Expected: A clear failure message surfaced to the user when Pilot's background run ended without producing an answer. The client does not silently retry on the same thread.
list_completed_dataset_extractions
Read-onlyList completed dataset extractions
List the dataset-extraction jobs you've completed in-app. Returns the same set the in-app reports page shows. Cursor-paginated. Each result includes the job's UUID, title, original query, last-updated timestamp, row count, and column schema.
Inputs
cursoroptionalOpaque cursor returned by a previous response'snextCursor. Omit to read from the most recent page.pageSizeoptionalPage size (1–100). Defaults to 25.
Example prompts
01“Show me my most recent dataset extractions.”
Expected: A page of completed extraction jobs ordered by recency, each with its
id,title, originalquery,rowCount, andcolumnSchema, plus anextCursorif more pages exist.02“List my completed dataset extractions and tell me which ones have a column for application number.”
Expected: A filtered view based on the returned
columnSchemaof each job, highlighting the jobs whose schemas match the criterion. Use theidof any match to feedget_dataset_extraction_rows.03“Page through my dataset extractions starting from cursor <cursor> and return up to 50 per page.”
Expected: The next page of extractions after the supplied cursor, capped at the requested page size, with a fresh
nextCursorwhen more data remains.
get_dataset_extraction_rows
Read-onlyGet dataset extraction rows
Read a page of extracted rows from a completed dataset-extraction job you started in-app. Cursor-paginated and scoped to your own jobs. Use this to pull the structured output of an extraction into the conversation for further analysis.
Inputs
jobIdrequiredThe dataset-extraction job UUID (fromlist_completed_dataset_extractions).cursoroptionalOpaque pagination cursor returned by a previous call. Omit for the first page.pageSizeoptionalRows per page (1–200). Defaults to 50.
Example prompts
01“Get the first 50 rows of dataset extraction job <jobId> and summarize the distribution of the decision_outcome column.”
Expected: The first 50 rows along with column definitions, followed by Pilot's tally of outcomes, usable as a quick read of a multi-hundred-row extraction.
02“Page through dataset extraction job <jobId>, 100 rows at a time, until you've seen everything; tell me which rows are missing a value in the effective_date column.”
Expected: Iterative reads using each response's
nextCursoruntil exhausted, with a consolidated list of rows whoseeffective_dateis null.03“Pull the next page of rows from job <jobId> using cursor <cursor>, then group the results by jurisdiction.”
Expected: The next page of rows after the supplied cursor, with a per-jurisdiction breakdown produced by Pilot from the returned data.
Privacy & data handling
Pilot MCP is scoped to the authenticated user's utility tenant. Tools only read data that user can already see in the Senpilot app. We don't share your data with third parties for advertising or model training. Full details are in the Senpilot privacy policy.
Limitations
- Pilot MCP is read-only. To create new dataset extractions or modify regulatory configuration, use the Senpilot app directly.
- Longer questions complete in two steps —
ask_pilot_regkicks off the work and the client checks back viaget_pilot_reg_resultsuntil the answer is ready. Most MCP clients handle this automatically. Citation URLs are short-lived presigned links (~1 hour). - Responses are bounded to fit MCP-host size limits (~150k characters). Long answers are truncated with a sentinel indicating the conversation can be continued via
threadId. - Dataset-extraction tools only show jobs you ran yourself inside Senpilot.
Support
Questions, bug reports, or feature requests? Email hello@senpilot.com and we'll get back to you.
