PersonalMCP
Provides Git inspection and repository operations within the approved workspace when Git is available and the workspace is a Git repository.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@PersonalMCP search the workspace for TODO comments and list them by file"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
PersonalMCP
A local Python MCP server that gives an MCP client (VS Code, Copilot CLI) read/write access to one approved workspace: file and directory CRUD, search, git, shell commands, Python tooling, data conversion, web fetch, HTTP testing, system diagnostics and a todo list (68 tools). It uses the official MCP Python SDK over stdio and does not invoke an LLM. All tools run under one security model: workspace confinement, protected-name denylist, secret redaction, hashed audit logging, size/time limits, and an optional operator policy. Set read_only for inspection only, or allow_commands=false to disable process execution. Tool groups are documented at docs://tools (or the get_tool_docs tool) and in src/personal_mcp/toolkit/resources.
Requirements
Python 3.11 or newer
Git is optional; Git inspection is disabled when it is unavailable or the workspace is not itself a repository
Install from the release ZIP for an offline installation, or install the pinned project dependencies from PyPI
Related MCP server: Cloud Harness MCP
Run from a checkout
python -m pip install .
python -m personal_mcp --workspace C:\path\to\workspace servepython -m pip install .
python -m personal_mcp --workspace "$HOME/project" serveThe server defaults to the current directory when no workspace is supplied. Configuration can be passed as JSON with --config; MCP_WORKSPACE_ROOT is the only supported environment override. See docs/configuration.md.
Administration
python -m personal_mcp --version
python -m personal_mcp validate-config
python -m personal_mcp self-test
python -m personal_mcp print-client-config
python -m personal_mcp diagnostics
python -m personal_mcp capability-manifestSee docs/installation.md, docs/security-and-guardrails.md, and docs/compatibility.md before deployment. Manual GitHub Copilot and VS Code validation is documented in tests/manual/github-copilot-vscode-validation.md.
Development
python -m unittest discover -s tests -v
python scripts/validate/validate_docs.py
python scripts/build/build_release.pyThis project is not affiliated with or an extension to GitHub Copilot or Visual Studio Code. See SECURITY.md for vulnerability reporting.
Available Tools
68 toolsapi_load_testA
Tiny load probe: send requests requests (max 200) with concurrency workers (max 20)
and report status counts, errors and latency percentiles. Use only against systems you own.
Inputs: url (required), method, timeout, requests, +1 more. Returns: result
check_tcp_portBRead-onlyIdempotent
Test whether a TCP connection to host:port succeeds, with connect time.
Inputs: host (required), port (required), timeout. Returns: result
cim_queryARead-onlyIdempotent
Query CIM/WMI classes via Get-CimInstance (Windows only), e.g. Win32_OperatingSystem,
Win32_LogicalDisk, Win32_NetworkAdapterConfiguration, Win32_Service. filter is a WQL
WHERE clause such as "DriveType=3". Read-only.
Inputs: class_name (required), limit, filter, namespace, +1 more. Returns: result
convert_dataA
Convert between json, yaml, toml, csv, xml and psd1 (PowerShell data files). Provide either path or text. from_format is inferred from the file extension when omitted. With output_path the result is written there; otherwise it is returned. Reading psd1 needs pwsh (restricted language mode, no code execution); XML uses @attr / #text conventions.
Inputs: to_format (required), path, text, from_format, +1 more. Returns: result
copy_pathB
Copy a file or directory inside the workspace. Never overwrites.
Inputs: source (required), destination (required). Returns: result
create_diagnostic_bundleB
Write a sanitized local diagnostic summary to the approved diagnostics directory.
Inputs: no named parameters. Returns: object
create_directoryC
Create a directory and any missing parents. Succeeds if it already exists.
Inputs: path (required). Returns: result
create_fileB
Create a file (and parent dirs) with the given content. Writes are atomic.
Inputs: path (required), content (required), overwrite. Returns: result
delete_fileADestructive
Delete a file or directory (recursively). Irreversible. Refuses the workspace root, trees that contain links, nested repositories or protected files, and huge trees.
Inputs: path (required). Returns: result
dns_lookupBRead-onlyIdempotent
Resolve a hostname to its addresses using the system resolver.
Inputs: host (required). Returns: result
edit_fileA
Replace old_string with new_string in a file. Fails unless it matches exactly once (or replace_all is true). dry_run=true returns a unified diff without writing.
Inputs: path (required), new_string (required), old_string (required), dry_run, +1 more. Returns: result
edit_file_multiADestructive
Apply several edits atomically. Each edit is {"old_string": ..., "new_string": ..., optional "replace_all": "true"}. Edits apply in order; if any fails nothing is written.
Inputs: path (required), edits (required), dry_run. Returns: result
environment_variablesBRead-onlyIdempotent
Environment variables of the server process. Values of secret-looking names are redacted.
Inputs: name_contains. Returns: result
format_codeB
Format Python code with ruff; check_only=True only reports.
Inputs: cwd, path, check_only. Returns: result
get_capability_helpA
Return the capability inventory or one capability's manifest entry.
Inputs: capability. Returns: object
get_file_metadataB
Return safe metadata for one file without reading its contents.
Inputs: path (required). Returns: object
get_tool_docsARead-onlyIdempotent
Return usage docs and examples for a toolkit group (filesystem, search, shell, git, python, web-fetch, data-conversion, api-testing, diagnostics, todo, policy) or 'index'. Call this after a tool error.
Inputs: topic. Returns: result
git_addC
Stage files.
Inputs: paths (required), repo. Returns: result
git_blameBRead-onlyIdempotent
Show who last changed each line of a file (read-only). Optionally limit to a line range.
Inputs: path (required), repo, end_line, start_line. Returns: result
git_branch_createA
Create a new branch (and optionally switch to it). Never overwrites an existing branch.
Inputs: name (required), repo, switch, start_point. Returns: result
git_branch_listARead-onlyIdempotent
List branches with their last commit and upstream (read-only). all_branches includes remotes.
Inputs: repo, all_branches. Returns: result
git_commitC
Commit staged changes.
Inputs: message (required), repo. Returns: result
git_diffBRead-onlyIdempotent
Show git diff (optionally staged and/or for one path).
Inputs: path, repo, staged. Returns: result
git_diff_statBRead-onlyIdempotent
Summarise changes per file (read-only), compact for large diffs. base compares with a revision.
Inputs: base, repo, staged. Returns: result
git_diff_summaryA
Return bounded diff statistics without patch contents.
Inputs: no named parameters. Returns: object
git_initB
Initialise a new git repository (non-destructive; existing repos are left intact).
Inputs: repo, initial_branch. Returns: result
git_logCRead-onlyIdempotent
Show recent commits.
Inputs: repo, max_count. Returns: result
git_pushADestructive
Push a branch (default: current) to a remote. Force pushes and ref deletion are not supported. tags=true pushes tags instead of a branch.
Inputs: repo, tags, branch, remote, +1 more. Returns: result
git_recent_historyB
Return a bounded list of recent commit summaries.
Inputs: limit. Returns: object
git_remote_infoARead-onlyIdempotent
List configured remotes and their URLs (read-only). Credentials in URLs are masked.
Inputs: repo. Returns: result
git_repository_statusB
Return bounded read-only Git status; no untracked filenames are enumerated.
Inputs: no named parameters. Returns: object
git_showBRead-onlyIdempotent
Show a commit's message and diff (read-only). stat_only=true gives only the file summary.
Inputs: rev, path, repo, stat_only. Returns: result
git_stash_listBRead-onlyIdempotent
List stashes (read-only).
Inputs: repo. Returns: result
git_statusCRead-onlyIdempotent
Show short git status.
Inputs: repo. Returns: result
git_switchB
Switch to an existing branch. Git refuses if it would overwrite local changes.
Inputs: name (required), repo. Returns: result
git_tag_createB
Create a tag (annotated if message given). Never moves or replaces an existing tag.
Inputs: name (required), repo, target, message. Returns: result
globARead-onlyIdempotent
Find files by glob pattern (e.g. '**/*.py'), relative to path. Skips git-ignored files unless respect_gitignore=false. Use offset to page.
Inputs: pattern (required), path, offset, max_results, +1 more. Returns: result
grepARead-onlyIdempotent
Regex search file contents. Returns path:line: text matches. Skips git-ignored files (and .git, node_modules, .venv) unless respect_gitignore=false. Use offset to page.
Inputs: pattern (required), path, offset, file_glob, +3 more. Returns: result
http_requestA
Send an HTTP request (localhost and private addresses allowed) and report status, timing, redacted headers and a truncated body. Optional assertions: expect_status, expect_json ({"data.items[0].id": 5} path->value), expect_contains (substring of body), max_latency_ms. Result begins with PASS/FAIL when assertions are given.
Inputs: url (required), body, method, params, +9 more. Returns: result
lintB
Lint Python code with ruff (optionally auto-fix).
Inputs: cwd, fix, path. Returns: result
list_directoryC
List one workspace directory. Use cursor for the next bounded page.
Inputs: path, cursor, page_size, include_hidden. Returns: object
list_portsBRead-onlyIdempotent
List TCP/UDP sockets with owning process. May need elevated rights to see other users' PIDs.
Inputs: protocol, listening_only. Returns: result
list_processesBRead-onlyIdempotent
List processes (pid, name, user, cpu%, memory) sorted by 'memory' or 'cpu' or 'pid'.
Inputs: limit, sort_by, name_contains. Returns: result
list_servicesBRead-onlyIdempotent
List services (systemd on Linux, Get-Service on Windows, launchctl on macOS). state: e.g. running / stopped (Windows) or running / failed / active (systemd).
Inputs: state, name_contains. Returns: result
markdown_to_scriptA
Extract code from a markdown file. Only fenced blocks tagged with language are kept
unless extract_all_blocks is true. Prose becomes comments when include_prose is true.
Inputs: path (required), language (required), output_path, include_prose, +1 more. Returns: result
move_pathBDestructive
Move or rename a file or directory inside the workspace. Never overwrites.
Inputs: source (required), destination (required). Returns: result
network_interfacesARead-onlyIdempotent
NIC configuration: addresses, netmask, MAC, MTU, speed and up/down state, plus I/O counters.
Inputs: no named parameters. Returns: result
pandoc_convertB
Convert documents with pandoc (docx, html, md, rst, pdf output needs a LaTeX engine...). Runs in --sandbox mode so the document cannot read other files or run filters.
Inputs: input_path (required), output_path (required), to_format, from_format. Returns: result
policy_infoARead-onlyIdempotent
Show whether an operator policy file exists and its contents (allow/deny lists, command deny patterns, web_fetch domain allow-list).
Inputs: no named parameters. Returns: result
query_dataBRead-onlyIdempotent
Extract values from a json/yaml/toml/csv/xml/psd1 file with a path expression such as 'servers[0].name', 'users[].email' or '.port'. Returns JSON (a list of matches).
Inputs: path (required), query (required), format. Returns: result
read_event_logsARead-onlyIdempotent
Recent system events. Linux: journalctl (source = unit name, level = minimum severity).
Windows: Get-WinEvent (source = log name, default 'System'; level = exact level).
macOS: log show. level: critical|error|warning|info|verbose.
Inputs: level, source, contains, max_entries, +1 more. Returns: result
read_text_fileC
Read a bounded UTF-8 excerpt from an approved workspace file.
Inputs: path (required), end_line, start_line. Returns: object
replace_linesA
Replace lines start_line..end_line (1-based, inclusive) with new_text. Use end_line=start_line-1 to insert before start_line.
Inputs: path (required), end_line (required), new_text (required), start_line (required), +1 more. Returns: result
run_commandADestructive
Run a shell command and return exit code, stdout and stderr. Uses PowerShell on Windows and the default shell elsewhere. The working directory must be inside the workspace (default: the workspace root). The command itself is NOT confined: a shell can still reach any path the server's user can. Secret-named environment variables are removed and output is redacted.
Inputs: command (required), cwd, timeout. Returns: result
run_testsC
Run pytest on a path with optional extra args (e.g. '-k name -x').
Inputs: cwd, args, path. Returns: result
script_to_markdownA
Convert a script into literate markdown: column-0 comment blocks (and PowerShell <# #> blocks) become prose, everything else becomes fenced code. Heuristic and meant for documentation; markdown_to_script reverses it.
Inputs: path (required), language, output_path. Returns: result
search_workspace_textC
Search bounded text files and return sanitized line excerpts.
Inputs: query (required), path, cursor, page_size, +1 more. Returns: object
server_healthB
Return safe server health, version, configuration state, and diagnostics status.
Inputs: no named parameters. Returns: object
service_statusCRead-onlyIdempotent
Detailed status of one service.
Inputs: name (required). Returns: result
summarize_project_structureC
Return a shallow, bounded inventory without reading file contents.
Inputs: max_files. Returns: object
system_infoARead-onlyIdempotent
OS, kernel, uptime, CPU, load, memory, swap and disk usage for this machine.
Inputs: no named parameters. Returns: result
todo_addA
Add a todo (status pending) to the workspace scratchpad and return the updated list.
Inputs: text (required). Returns: result
todo_listARead-onlyIdempotent
List the workspace todo scratchpad. Optional status filter: pending, in_progress, done.
Inputs: status. Returns: result
todo_removeA
Remove one todo from the scratchpad by id; returns the updated list.
Inputs: id (required). Returns: result
todo_updateA
Change a todo's status (pending, in_progress, done) and/or text; returns the updated list.
Inputs: id (required), text, status. Returns: result
validate_server_configurationB
Validate the loaded configuration without returning machine-specific paths.
Inputs: no named parameters. Returns: object
web_fetchA
Download a web page (after explicit user confirmation), sanitise it and save it as a local markdown file. Returns the file path only; read the file to consume it. Executable/archive/ document extensions and non-text content types are rejected; scripts, forms, iframes, event handlers and unsafe links are stripped. Private/loopback addresses are blocked.
Inputs: url (required), output_dir. Returns: result
workspace_infoA
Return an opaque workspace identifier and active safety limits.
Inputs: no named parameters. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 68 tools
Tools are grouped into clear domains, but several within-domain pairs overlap heavily: git_status vs git_repository_status, git_log vs git_recent_history, and git_diff vs git_diff_summary vs git_diff_stat. Descriptions help distinguish bounded/read-only variants, but an agent could still easily misselect among them.
All names are snake_case, which is consistent, but the structural convention is mixed: verb_noun (list_directory, read_text_file), noun_verb (todo_list, git_status), and noun_noun (service_status, git_repository_status) all appear. The domain prefixes help readability, but there is no single predictable pattern.
With 68 tools, the surface is extremely large even for a broad personal automation server, and several tools duplicate existing read-only git functionality. This is squarely in the 50+ extreme-count range and makes discovery and selection harder.
The server covers filesystem, search, shell, Python tooling, git, data conversion, web/API testing, diagnostics, todos, and system inspection with broad lifecycle support. The main gaps are git network/workflow operations such as clone/fetch/pull/merge and service or process control, though run_command provides a workaround.
Maintenance
Related MCP Connectors
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
Read and write shared BitsWeave context, projects, tasks, and work sessions through MCP.
One MCP endpoint for your company's tools, with per-person sign-in, policy and audit.
Query, browse, and automate OmegaAI workspaces from any MCP client. Streamable HTTP with OAuth 2.0.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceExposes a secure, path-confined bridge to a local workspace and git remotes, enabling MCP clients to search, read, write, reset files, and perform git operations.-
- AlicenseNot gradedqualityBmaintenanceEnables AI clients to securely operate isolated coding workspaces with file, command, Git, and deployment tools via authenticated remote MCP.106MIT
- AlicenseAqualityBmaintenanceEnables MCP clients to safely read, write, edit, search, and optionally run commands within one or more named project workspaces, while maintaining a work journal and tracking changes.19MIT
- AlicenseNot gradedqualityCmaintenanceEnables managed access to workspace file operations, background tasks, Skills, and upstream MCP services through a unified web console with workspace-bound keys and explicit tool permissions.MIT