Content
#+TITLE: MCP.el - Model Context Protocol for Emacs
[[https://melpa.org/#/mcp][file:https://melpa.org/packages/mcp-badge.svg]]
[[https://www.gnu.org/licenses/gpl-3.0][https://img.shields.io/badge/License-GPLv3-blue.svg]]
This is an Emacs client for interfacing with [[https://modelcontextprotocol.io/introduction][MCP]], supporting connections to MCP servers.
* Features
- Structured communication with MCP servers
- Support for filesystem and generic MCP servers
- Extensible tool and prompt system
- Asynchronous and synchronous operations
- Resource management capabilities
- Intuitive interface for managing server lifecycle (start/stop/restart)
- Integration with popular Emacs packages (e.g., gptel, llm)
* Installation
Need Emacs 30 or higher version
#+begin_src elisp
(use-package mcp
:ensure t
:after gptel
:custom (mcp-hub-servers
`(("filesystem" . (:command "npx" :args ("-y" "@modelcontextprotocol/server-filesystem" "/home/lizqwer/MyProject/")))
("fetch" . (:command "uvx" :args ("mcp-server-fetch")))
("qdrant" . (:url "http://localhost:8000/sse"))
("graphlit" . (
:command "npx"
:args ("-y" "graphlit-mcp-server")
:env (
:GRAPHLIT_ORGANIZATION_ID "your-organization-id"
:GRAPHLIT_ENVIRONMENT_ID "your-environment-id"
:GRAPHLIT_JWT_SECRET "your-jwt-secret")))))
:config (require 'mcp-hub)
:hook (after-init . mcp-hub-start-all-server))
#+end_src
* Usage
** Mcp hub
*** Configuring MCP Servers
#+begin_src elisp
(setq mcp-hub-servers
'(("filesystem" . (:command "npx" :args ("-y" "@modelcontextprotocol/server-filesystem" "/home/lizqwer/MyProject/")))
("fetch" . (:command "uvx" :args ("mcp-server-fetch")))
("qdrant" . (:url "http://localhost:8000/sse"))
("graphlit" . (
:command "npx"
:args ("-y" "graphlit-mcp-server")
:env (
:GRAPHLIT_ORGANIZATION_ID "your-organization-id"
:GRAPHLIT_ENVIRONMENT_ID "your-environment-id"
:GRAPHLIT_JWT_SECRET "your-jwt-secret")))))
#+end_src
You can use =mcp-hub-start-all-server= to start all MCP servers, such as launching all MCP servers after starting Emacs.
#+begin_src elisp
(add-hook 'after-init-hook
#'mcp-hub-start-all-server)
#+end_src
*** Managing MCP Servers
Use =mcp-hub= to launch the server management interface, which will automatically start all configured MCP servers.
#+html: <img src="https://github.com/user-attachments/assets/31877c0b-d71a-491d-9830-2afed8d6218a" alt="mcp-hub"/>
*** Keymap
| key | function | description |
|-----+----------------------------+-----------------------------------------|
| l | mcp-hub-view-log | View server logs |
| s | mcp-hub-start-server | Start server under cursor |
| k | mcp-hub-close-server | Stop server under cursor |
| r | mcp-hub-restart-server | Restart server under cursor |
| S | mcp-hub-start-all-server | Start all configured servers |
| R | mcp-hub-restart-all-server | Restart all configured servers |
| K | mcp-hub-close-all-server | Stop all running servers |
*** use with [[https://github.com/karthink/gptel][gptel]]
- For =gptel= integration, See the [[https://github.com/karthink/gptel?tab=readme-ov-file#model-context-protocol-mcp-integration][gptel mcp]] for details.
- [[https://github.com/lizqwerscott/gptel-mcp.el][gptel-mcp.el]] is interface integration for gptel.el and mcp.el
** Example [[https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem][filesystem]] server.
*** Establish the connection first.
#+begin_src elisp
(mcp-connect-server "filesystem" :command "npx" :args '("-y" "@modelcontextprotocol/server-filesystem" "~/Downloads/")
:initial-callback
#'(lambda (connection)
(message "%s connection" (jsonrpc-name connection)))
:tools-callback
#'(lambda (connection tools)
(message "%s tools: %s" (jsonrpc-name connection) tools))
:prompts-callback
#'(lambda (connection prompts)
(message "%s prompts: %s" (jsonrpc-name connection) prompts))
:resources-callback
#'(lambda (connection resources)
(message "%s resources: %s" (jsonrpc-name connection) resources)))
#+end_src
*** Define the use of tools.
The current text is being tested using the [[https://github.com/karthink/gptel/issues/514][gptel tool]] branch.Use =mcp-make-text-tool= to create standard tool call data ([[https://github.com/ahyatt/llm/discussions/124][Discussions]]).It is recommended to create tools within the tools-callback or wait for the mcp connect server to complete.
#+begin_src elisp
(mcp-make-text-tool "filesystem" "write_file")
#+end_src
This will generate a data structure where the function is an auto-generated synchronous or asynchronous lambda function for accessing the MCP server.
#+begin_src elisp
(list :function #'(lambda (&rest args)
;; Synchronous or asynchronous access to the MCP server's Lambda function.
)
:name "write_file"
:async nil
:description "Create a new file or completely overwrite an existing file with new content. Use with caution as it will overwrite existing files without warning. Handles text content with proper encoding. Only works within allowed directories."
:args ((:type "string" :name "path" :description "path")
(:type "string" :name "content" :description "content"))
:category "files")
#+end_src
*** Disconnect from the server.
#+begin_src elisp
(mcp-stop-server "filesystem")
#+end_src
*** Manual function call
**** Synchronize
#+begin_src elisp
(let ((connection (gethash "filesystem" mcp-server-connections)))
(mcp-call-tool connection "write_file" '(:path "filename or file path" :content "the file content")))
#+end_src
**** Asynchronous
#+begin_src elisp
(let ((connection (gethash "filesystem" mcp-server-connections)))
(mcp-async-call-tool connection
"write_file"
'(:path "filename or file path" :content "the file content")
#'(lambda (res)
;; handle res
(mcp--parse-tool-call-result res))
#'(lambda (code message)
;; handle error
(format "call %s tool error with %s: %s"
tool-name
code
message))))
#+end_src
*** Manual get prompt
Since the [[https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem][filesystem]] lacks prompts, the [[https://github.com/modelcontextprotocol/servers/tree/main/src/everything][everything]] server is used for demonstration.
**** Synchronize
#+begin_src elisp
(let ((connection (gethash "everything" mcp-server-connections)))
(mcp-get-prompt connection "complex_prompt" '(:temperature "1.0")))
#+end_src
**** Asynchronous
#+begin_src elisp
(let ((connection (gethash "everything" mcp-server-connections)))
(mcp-async-get-prompt connection
"complex_prompt"
'(:temperature "1.0")
#'(lambda (res)
(message "prompt: %s" res))
#'(lambda (code message)
(message "error call: %s, %s" code message))))
#+end_src
*** Manual get resources
Since the [[https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem][filesystem]] lacks resources, the [[https://github.com/modelcontextprotocol/servers/tree/main/src/everything][everything]] server is used for demonstration.
**** Synchronize
#+begin_src elisp
(let ((connection (gethash "everything" mcp-server-connections)))
(mcp-read-resource connection "test://static/resource/1"))
#+end_src
**** Asynchronous
#+begin_src elisp
(let ((connection (gethash "everything" mcp-server-connections)))
(mcp-async-read-resource connection "test://static/resource/1"
#'(lambda (resource)
(message "res: %s" resource))))
#+end_src
*** Get resource templates
Since the [[https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem][filesystem]] lacks resources, the [[https://github.com/modelcontextprotocol/servers/tree/main/src/everything][everything]] server is used for demonstration.
#+begin_src elisp
(let ((connection (gethash "everything" mcp-server-connections)))
(mcp-async-list-resource-templates connection
#'(lambda (connection templates)
(message "%s" templates))))
#+end_src
* Roadmap
- [X] HTTP SSE based MCP server connections
- [ ] mcp marketplace (browser and auto install mcp server)
- [ ] Simplified integration with other Emacs AI clients
- [ ] Expanded documentation
- [ ] Full MCP protocol client implementation
* License
This project is licensed under the GNU General Public License v3.0 - see the [[file:LICENSE][LICENSE]] file for details.
Connection Info
You Might Also Like
MarkItDown MCP
MarkItDown-MCP is a lightweight server for converting various URIs to Markdown.
Context 7
Context7 MCP provides up-to-date code documentation for any prompt.

Continue
Continue is an open-source project for enhancing MCP Server functionality.
semantic-kernel
Build and deploy intelligent AI agents with the Semantic Kernel framework.
Github
GitHub MCP Server connects AI tools to manage repositories, issues, and workflows.
Playwright
A lightweight MCP server for browser automation using Playwright, enabling...