Copilot Tools Gateway exposes Microsoft Copilot account capabilities as local tools for agentic coding assistants. It is designed for OpenCode, Codex, Claude Desktop, and other MCP-capable clients that already have their own primary LLM.
This project is not a selectable coding model. It provides auxiliary Copilot tools for chat, image generation, image analysis, and file-assisted questions when the signed-in account supports those capabilities.
Unofficial project. This repository is not affiliated with Microsoft. It uses your own Microsoft account session locally. Use it responsibly and follow the service terms that apply to your account.
Requirements:
- Python 3.11 or newer.
- Windows, macOS, or Linux.
- A Microsoft account with access to the Copilot surface you want to use.
The fastest path is consumer Copilot:
- Install the project.
- Run
python -m copilot_tools_gateway login consumer. - Add the MCP server to your client.
- Use
model: "copilot"for chat, image generation, and image analysis.
Use m365-copilot only when the signed-in account has Microsoft 365 Copilot or
eligible Office 365 access. M365 is the provider for document attachments.
Clone the repository and enter it:
git clone https://github.com/yurilopes/Copilot-Tools-Gateway.git
cd Copilot-Tools-GatewayWindows PowerShell:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev,mcp]"Unix shells:
python -m venv .venv
. .venv/bin/activate
python -m pip install -e ".[dev,mcp]"If you plan to use m365-copilot, install the Playwright Chromium browser for
the Microsoft 365 assisted login and refresh flow:
python -m playwright install chromiumCreate at least one provider session.
Consumer Copilot:
python -m copilot_tools_gateway login consumerMicrosoft 365 Copilot:
python -m copilot_tools_gateway login m365Run the MCP server over stdio:
python -m copilot_tools_gateway mcpThe installed script is also available after installation:
copilot-tools-gateway mcpUse python -m copilot_tools_gateway ... in examples when you want the most
portable local command from the repository checkout.
Add this stdio server to your MCP client configuration:
{
"mcpServers": {
"copilot-tools-gateway": {
"command": "python",
"args": ["-m", "copilot_tools_gateway", "mcp"]
}
}
}If the client runs outside this repository or virtual environment, replace
python with the absolute path to the environment interpreter.
See docs/mcp.md for the complete MCP reference, tool schemas, response envelope, provider limitations, and agent recovery guidance.
MCP tools:
copilot_statuscopilot_list_conversationscopilot_chatcopilot_generate_imagecopilot_visioncopilot_chat_with_files
OpenAI-compatible HTTP compatibility surface:
GET /v1/modelsPOST /v1/chat/completionsPOST /v1/images/generations
Provider models:
copilot-autochooses a valid configured provider automatically.m365-copilotuses Microsoft 365 Copilot and requires an account with Microsoft 365 Copilot or eligible Office 365 access.copilotuses consumer Microsoft Copilot.
MCP is the primary integration surface. The HTTP API exists for simple local compatibility.
Use copilot-auto by default. It prefers M365 when both providers are
available because M365 usually has broader file and enterprise capabilities.
Use m365-copilot when your account has Microsoft 365 Copilot or eligible
Office 365 access and you need document attachments, Graph-backed file access,
or M365 conversation behavior. Do not use this provider with a consumer-only
Microsoft account. The M365 attachment matrix has been validated through MCP
for DOCX, PDF, XLSX, PPTX, TXT, and larger DOCX files.
Use copilot when you want the consumer Microsoft Copilot account. Consumer
Copilot supports chat, image generation, and PNG or JPEG image attachments. It
tries direct WebSocket image analysis first and uses Pydoll browser-assisted
image chat as an explicit fallback for recoverable image protocol failures. It
does not support document attachments through this gateway yet.
Login and refresh are CLI operations, not MCP tools. MCP tools return agent-friendly recovery instructions when a provider needs login, refresh, or a browser warm-up.
M365 login:
python -m copilot_tools_gateway login m365M365 refresh:
python -m copilot_tools_gateway refresh m365The M365 refresh command reuses the persistent browser profile and waits for safe capture signals for Copilot, Graph, and search access. If document access does not refresh silently, it asks the user to complete safe browser steps such as sending a normal message or attaching a small document.
Consumer login:
python -m copilot_tools_gateway login consumerConsumer refresh and browser warm-up:
python -m copilot_tools_gateway refresh consumerConsumer login and refresh use Pydoll with a persistent Chromium profile. This avoids the empty challenge modal behavior that can appear in Playwright-driven consumer sessions.
Consumer Copilot may require a browser challenge before non-browser WebSocket
chat is accepted. When that happens, run refresh consumer, complete any
challenge in the opened browser, send one normal Copilot message, wait for the
answer, and retry the original MCP or HTTP request.
When an agent or automation runs refresh consumer without interactive
terminal input, the command prints the same browser warm-up instructions and
continues with safe session capture instead of failing on stdin.
Sessions are stored under session/, which is ignored by Git. Do not commit or
share session files.
After login, start with:
python -m copilot_tools_gateway mcpCheck provider status through an MCP client by calling:
copilot_status
Run safe local health checks from the terminal:
python -m copilot_tools_gateway doctorList resumable conversations:
{
"model": "copilot",
"limit": 20
}The list returns conversation titles and conversation_id values only. Pass a
returned conversation_id to copilot_chat, copilot_vision, or
copilot_chat_with_files to resume that thread. Consumer and M365 conversation
listing use direct API calls. M365 listing requires the web session captured by
login m365 or refresh m365 and currently returns the initial sidebar page
with local pagination for that initial page. Remote scroll pagination is not
validated yet.
Ask for simple chat:
{
"prompt": "Say hello in one short sentence.",
"model": "copilot-auto"
}Analyze an image with consumer Copilot:
{
"image_path": "C:\\path\\to\\image.png",
"prompt": "Describe the image.",
"model": "copilot"
}Successful consumer image calls include safe MCP diagnostics such as
attachment_backend, direct_attempted, and fallback_used.
Ask about a document with M365 Copilot:
{
"file_paths": ["C:\\path\\to\\document.docx"],
"prompt": "Summarize this document and quote its validation marker.",
"model": "m365-copilot"
}Start the local API:
python -m copilot_tools_gateway apiThe default URL is http://127.0.0.1:3991/v1.
List models:
curl http://127.0.0.1:3991/v1/modelsChat:
curl http://127.0.0.1:3991/v1/chat/completions \
-H "Content-Type: application/json" \
-d "{\"model\":\"copilot-auto\",\"messages\":[{\"role\":\"user\",\"content\":\"Say hello in one short sentence.\"}]}"Optional diagnostics live under tools/diagnostics/. They are not part of
normal MCP or HTTP operation.
Consumer WebSocket health check:
python tools/diagnostics/check_consumer_websocket_health.pyConsumer image protocol v2 discovery:
python tools/diagnostics/check_consumer_image_protocol_v2.pyM365 attachment matrix check:
python tools/diagnostics/check_m365_attachment_matrix.pyConversation list protocol check:
python tools/diagnostics/check_conversation_list_protocol.pyMCP smoke check through stdio:
python tools/diagnostics/check_mcp_smoke.pyFor M365 sidebar discovery, add --m365-ui. If the persistent browser profile is
not signed in, the sanitized result includes a recommended_action telling the
operator to sign in and rerun the diagnostic.
The UI diagnostic records only sanitized request, response, and WebSocket URL
metadata such as host, path, query key names, status, and JSON shape.
Runtime M365 conversation listing uses the direct endpoint validated by this
diagnostic and does not require browser automation during MCP tool calls.
Generate validation files without calling MCP:
python tools/diagnostics/check_m365_attachment_matrix.py --generate-onlyDiagnostics append sanitized operational results under captures/. They must
not store tokens, cookies, browser storage, raw requests, raw responses, or
session file contents.
- The project uses unofficial Copilot web protocols that can change without notice.
- Login and refresh are CLI flows, not MCP tools.
- M365 document attachments require an eligible Microsoft 365 Copilot or Office 365 account plus refreshed Graph and search access.
- M365 conversation listing returns the initial sidebar page and local pagination for that page. Remote scroll pagination is not validated yet.
- Consumer document attachments are not supported. Use
m365-copilotfor documents. - Consumer Copilot can require browser warm-up before non-browser WebSocket requests are accepted.
- Diagnostics are sanitized by design and should not include prompts, answers, session files, cookies, tokens, browser storage, or raw upstream traffic.
- Runtime sessions, cookies, and tokens stay under
session/. - AI-generated content is private by default.
- Public APIs return normalized gateway data, not raw vendor payloads.
- MCP diagnostics contain safe operational metadata only.
- Agents should never ask users to paste cookies, tokens, browser storage, session files, or raw upstream requests.
Run checks with explicit timeouts in your automation:
.\.venv\Scripts\python.exe -m pytest tests --basetemp "$env:TEMP\ctg-pytest-full"
.\.venv\Scripts\python.exe -m ruff check src tests tools/diagnostics
.\.venv\Scripts\python.exe -m mypy srcUse the repository virtual environment for validation. The project targets Python 3.11 or newer, and local global Python installations may contain stubs that do not match the configured mypy target.
The project uses small modules, explicit provider contracts, and strict typing.
See AGENTS.md and code-style.md before changing architecture.
