This is an Emacs client for interfacing with MCP, supporting connections to MCP servers.
Need Emacs 30 or higher version
(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))
(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")))))
You can use mcp-hub-start-all-server
to start all MCP servers, such as launching all MCP servers after starting Emacs.
(add-hook 'after-init-hook #'mcp-hub-start-all-server)
Use mcp-hub
to launch the server management interface, which will automatically start all configured MCP servers.
gptel
integration, See the gptel mcp for details.(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)))
The current text is being tested using the gptel tool branch.Use mcp-make-text-tool
to create standard tool call data (Discussions).It is recommended to create tools within the tools-callback or wait for the mcp connect server to complete.
(mcp-make-text-tool "filesystem" "write_file")
This will generate a data structure where the function is an auto-generated synchronous or asynchronous lambda function for accessing the MCP server.
(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")Disconnect from the server.
(mcp-stop-server "filesystem")
(let ((connection (gethash "filesystem" mcp-server-connections))) (mcp-call-tool connection "write_file" '(:path "filename or file path" :content "the file content")))
(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))))
Since the filesystem lacks prompts, the everything server is used for demonstration.
(let ((connection (gethash "everything" mcp-server-connections))) (mcp-get-prompt connection "complex_prompt" '(:temperature "1.0")))
(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))))
Since the filesystem lacks resources, the everything server is used for demonstration.
(let ((connection (gethash "everything" mcp-server-connections))) (mcp-read-resource connection "test://static/resource/1"))
(let ((connection (gethash "everything" mcp-server-connections))) (mcp-async-read-resource connection "test://static/resource/1" #'(lambda (resource) (message "res: %s" resource))))
Since the filesystem lacks resources, the everything server is used for demonstration.
(let ((connection (gethash "everything" mcp-server-connections))) (mcp-async-list-resource-templates connection #'(lambda (connection templates) (message "%s" templates))))
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4