copilot-mcp
# copilot-mcp
A simple Python MCP server (stdio) exposing Copilot-style tools to VS Code.
| Group | Tools |
|---|---|
| Docs | `get_tool_docs` (also resources `docs://tools`, `docs://tools/{group}`) |
| Filesystem | `workspace_info`, `read_file`, `create_file`, `edit_file`, `edit_file_multi`, `replace_lines`, `list_dir`, `delete_file` |
| Search | `grep`, `glob` |
| Shell | `run_command` |
| Git | `git_status`, `git_diff`, `git_log`, `git_add`, `git_commit`, `git_init`, `git_branch_create`, `git_switch`, `git_tag_create`, `git_push`, `git_blame`, `git_show`, `git_branch_list`, `git_stash_list`, `git_remote_info`, `git_diff_stat` |
| Python | `run_tests`, `lint`, `format_code` |
| Web | `web_fetch` (confirmation required, saves sanitised markdown) |
| Data / docs | `convert_data`, `query_data`, `script_to_markdown`, `markdown_to_script`, `pandoc_convert` |
| API testing | `http_request` (with assertions), `api_load_test` |
| Todo scratchpad | `todo_list`, `todo_add`, `todo_update`, `todo_remove` |
| Policy / audit | `policy_info`, `audit_tail` (optional policy file and audit log, see [docs/tools/policy.md](docs/tools/policy.md)) |
| Diagnostics | `system_info`, `list_processes`, `list_ports`, `network_interfaces`, `dns_lookup`, `check_tcp_port`, `list_services`, `service_status`, `read_event_logs`, `cim_query`, `environment_variables` |
> **Workspace-focused.** File, search, git, Python and conversion tools only touch paths inside the open workspace (set by `COPILOT_MCP_WORKSPACE`, normally `${workspaceFolder}`); relative paths resolve against it, and `..` or symlink escapes are rejected. **`run_command` is not confined:** its working directory must be in the workspace, but the command itself runs with your user's permissions. See [docs/security.md](docs/security.md).
## Behaviour notes
- **Edits:** `edit_file`, `edit_file_multi` and `replace_lines` accept `dry_run=true` to return a unified diff. Multi-edits are atomic.
- **Git:** only creation and push are exposed. There is no force push, branch/tag/ref deletion, reset or rebase; refs are validated so `+ref`, `:ref` and option-like names are rejected.
- **`web_fetch`:** asks for confirmation through MCP elicitation on every call and refuses if the client cannot ask. It blocks non-http(s) URLs, embedded credentials, private/loopback/link-local hosts (re-checked on every redirect), executable/archive/document extensions (including in `Content-Disposition` and double extensions) and non-text content types. HTML is stripped of scripts, forms, frames, event handlers, `javascript:`/`data:` links, comments and invisible/bidi characters before conversion. It returns only the path of the saved `.md` file (default `./fetched/`). Fetched text is still untrusted input for the model.
- **`convert_data`:** json, yaml, toml, csv, xml and psd1. Reading `.psd1` uses `Import-PowerShellDataFile` through PowerShell (`pwsh` if present, else Windows PowerShell 5.1; no code execution); writing is done natively. XML is parsed with `defusedxml`. `pandoc_convert` needs `pandoc` installed and runs with `--sandbox`.
- **`script_to_markdown` / `markdown_to_script`:** heuristic literate conversion (column-0 comments are prose, other lines are code).
- **API testing:** `http_request` may target localhost and private addresses, unlike `web_fetch`. Sensitive response headers are redacted.
- **Diagnostics:** read-only and cross-platform (systemd/journalctl on Linux, PowerShell on Windows, launchctl/`log` on macOS). `cim_query` works on Windows only. Listing other users' socket owners may need elevated rights.
## Documentation
Build a deployable zip with `python scripts/build.py` (see [docs/development.md](docs/development.md)).
Full documentation lives in [docs/](docs/README.md): [getting started](docs/getting-started.md), [architecture](docs/architecture.md), [security model](docs/security.md), [development guide](docs/development.md), and a detailed page per tool group under [docs/tools/](docs/tools).
## Setup
```sh
python -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest
```
## VS Code
[.vscode/mcp.json](.vscode/mcp.json) registers the server. Open the folder in VS Code, run
**MCP: List Servers**, start (or restart after code changes) `copilot-mcp`, then use Agent mode in Copilot Chat.
## Adding tools
Add a function with type hints and a docstring to a module in `src/copilot_mcp/tools/`, list it in that module's `TOOLS`, and register new modules in `server.py`.
## License
[MIT](LICENSE) (c) 2026 Josh Hollandsworth. Provided as is, without warranty; see the license for details.
TDQS
Scored across 56 tools
Most tools target clearly different resources or actions, and the domain grouping helps agents choose correctly. There is some overlap among file-editing tools (edit_file, edit_file_multi, replace_lines) and between run_command and specialized tools like run_tests/lint/format_code, but descriptions make the intended boundaries reasonably clear.
All names use snake_case and several domain prefixes (git_, todo_) provide useful grouping. However, the naming pattern mixes verb_noun (read_file, list_dir), noun_verb/prefix_noun_verb (git_branch_create, todo_add), and bare nouns (grep, glob, lint), so it is readable but not fully predictable.
56 tools is far above the typical well-scoped range and is likely to burden tool selection and context use. The tools are grouped sensibly by domain, but the overall surface is too large for a single MCP server.
The server covers a very broad coding-assistant surface: filesystem operations, git workflows, Python lint/test/format, web/API testing, diagnostics, data conversion, todos, and policy/audit helpers. Some lifecycle operations are missing or indirect, such as git pull/fetch/merge/clone and file move/copy, but run_command provides a fallback for many gaps.