Feat: Add ai-code Emacs MCP server. AI Code Agent is able to get info… · Superbil/ai-code-interface.el@f01c19c · GitHub
Skip to content

Commit f01c19c

Browse files
authored
Feat: Add ai-code Emacs MCP server. AI Code Agent is able to get information from emacs with these MCP (tninja#228)
* Add ai-code MCP server and tests * Document built-in Emacs MCP tools core and usage * Document how to verify MCP setup and test tools * Add post-start hook to session creation * Integrate MCP agent into GitHub Copilot CLI * Add MCP HTTP server, agent adapters and tests * Send HTTP 202 for notifications and empty schemas * Add instructions to register MCP tool in README, verified it works * update HISTORY * Addressing feedbacks
1 parent 6bd59c9 commit f01c19c

15 files changed

Lines changed: 1482 additions & 13 deletions

‎HISTORY.org‎

Lines changed: 1 addition & 0 deletions

‎README.org‎

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,92 @@ The generated prompt will include the function/region scope, visible file list,
166166
- [[https://github.com/crystaldba/postgres-mcp][Postgresql MCP]] / Sqlite MCP
167167
- [[https://github.com/docker/mcp-gateway][Docker]] / [[https://github.com/containers/kubernetes-mcp-server][Kubernetes]] MCP
168168

169+
**** Built-in Emacs MCP Tools
170+
171+
AI Code includes an Emacs MCP server with these built-in tools:
172+
- =project_info=
173+
- =imenu_list_symbols=
174+
- =xref_find_references=
175+
- =treesit_info=
176+
177+
***** Use It with an AI CLI
178+
179+
Set the backend to =codex= or =github-copilot-cli= and start a session with =C-c a a=. AI Code will:
180+
- start a local Emacs MCP HTTP server
181+
- register the current project/buffer as the MCP session context
182+
- inject a session-scoped MCP config into that agent session automatically
183+
184+
Today this auto-wiring is enabled for =codex= and =github-copilot-cli=. The adapter layer is designed so other backends can be added later.
185+
186+
If you disabled it before, enable it again with:
187+
188+
#+begin_src emacs-lisp
189+
(setq ai-code-mcp-agent-enabled-backends '(codex github-copilot-cli))
190+
#+end_src
191+
192+
***** Make Sure It Works
193+
194+
1. Start =codex= or =github-copilot-cli= with =C-c a a= from the file or project you want to work on.
195+
2. Switch to the agent buffer and run =M-x ai-code-mcp-agent-show-buffer-status=.
196+
197+
If it shows =:backend=, =:session-id=, and a local =:server-url=, then Emacs has attached MCP to this session.
198+
199+
3. Then ask the agent to use one of the Emacs tools, for example:
200+
- use =project_info= and tell me the current project info
201+
- use =imenu_list_symbols= for the current file
202+
203+
The status command only proves the Emacs side is wired.
204+
The real proof is that the started agent returns your current project path, buffer context, or current-file symbols from those tools.
205+
206+
***** Add New MCP function
207+
208+
1. Define an Emacs Lisp function.
209+
210+
#+begin_src emacs-lisp
211+
(defun ai-code-mcp-current-buffer-name ()
212+
"Return the current buffer name for the active MCP session."
213+
(buffer-name (current-buffer)))
214+
#+end_src
215+
216+
2. Register it as an MCP tool before you start the AI agent session:
217+
218+
#+begin_src emacs-lisp
219+
(require 'ai-code-mcp-server)
220+
221+
(ai-code-mcp-make-tool
222+
:function #'ai-code-mcp-current-buffer-name
223+
:name "current_buffer_name"
224+
:description "Return the current Emacs buffer name."
225+
:args nil)
226+
#+end_src
227+
228+
3. Start =codex= or =github-copilot-cli= with =C-c a a=.
229+
If the agent session is already running, restart it after registering the new tool.
230+
231+
4. Ask the agent to use the tool, for example:
232+
- use =current_buffer_name= and tell me the current Emacs buffer name
233+
234+
5. If you want to verify from Emacs first, run:
235+
236+
#+begin_src emacs-lisp
237+
(ai-code-mcp-dispatch "tools/list")
238+
#+end_src
239+
240+
If =current_buffer_name= appears in the tool list, Emacs has registered it.
241+
If the started agent can call it and returns the expected buffer name, the tool is available inside the AI coding agent.
242+
243+
***** Use the MCP Core Directly from Elisp
244+
245+
If you want to use the MCP core without an AI CLI, you can still call it directly:
246+
247+
#+begin_src emacs-lisp
248+
(require 'ai-code-mcp-server)
249+
(ai-code-mcp-builtins-setup)
250+
(ai-code-mcp-dispatch "tools/list")
251+
#+end_src
252+
253+
To expose your own Emacs function as a tool, use =ai-code-mcp-make-tool=.
254+
169255
- [[https://martinfowler.com/articles/exploring-gen-ai/context-engineering-coding-agents.html][Context Engineering for Coding Agents]], recommended by Martin Fowler.
170256

171257
*** Harness Engineering Practice

‎ai-code-backends-infra.el‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,8 @@ any error output left behind by the CLI."
754754
(defun ai-code-backends-infra--toggle-or-create-session (working-dir buffer-name process-table command
755755
&optional escape-fn cleanup-fn
756756
instance-name prefix force-prompt
757-
env-vars multiline-input-sequence)
757+
env-vars multiline-input-sequence
758+
post-start-fn)
758759
"Toggle or create a terminal session.
759760
WORKING-DIR is the directory for the session.
760761
BUFFER-NAME is the terminal buffer name.
@@ -768,7 +769,9 @@ When FORCE-PROMPT is non-nil, always prompt for a new instance name.
768769
ENV-VARS is a list of additional environment variable strings (e.g., \"VAR=value\")
769770
passed to the terminal session on creation.
770771
MULTILINE-INPUT-SEQUENCE configures `S-<return>' and `C-<return>' to send
771-
that sequence inside the session buffer."
772+
that sequence inside the session buffer.
773+
POST-START-FN is called with (BUFFER PROCESS INSTANCE-NAME) after a new
774+
session starts successfully."
772775
(setq process-table (or process-table ai-code-backends-infra--processes))
773776
(ai-code-backends-infra--cleanup-dead-processes process-table)
774777
(let* ((existing-buffers (and prefix
@@ -829,8 +832,10 @@ that sequence inside the session buffer."
829832
event)
830833
(when cleanup-fn
831834
(funcall cleanup-fn))))
832-
(ai-code-backends-infra--configure-session-buffer
833-
new-buffer escape-fn multiline-input-sequence)
835+
(ai-code-backends-infra--configure-session-buffer
836+
new-buffer escape-fn multiline-input-sequence)
837+
(when post-start-fn
838+
(funcall post-start-fn new-buffer process resolved-instance))
834839
(with-current-buffer new-buffer
835840
(add-hook 'kill-buffer-hook
836841
(lambda ()

‎ai-code-codex-cli.el‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
(require 'ai-code-backends)
1414
(require 'ai-code-backends-infra)
15+
(require 'ai-code-mcp-agent)
1516

1617
(defgroup ai-code-codex-cli nil
1718
"Codex CLI integration via `ai-code-backends-infra'."
@@ -46,17 +47,24 @@ With prefix ARG, prompt for CLI args using
4647
ai-code-codex-cli-program-switches
4748
arg
4849
"Codex"))
49-
(command (plist-get resolved :command)))
50+
(command (plist-get resolved :command))
51+
(mcp-launch (ai-code-mcp-agent-prepare-launch 'codex working-dir command))
52+
(launch-command (or (plist-get mcp-launch :command) command))
53+
(cleanup-fn (plist-get mcp-launch :cleanup-fn))
54+
(post-start-fn (plist-get mcp-launch :post-start-fn)))
5055
(ai-code-backends-infra--toggle-or-create-session
5156
working-dir
5257
nil
5358
ai-code-codex-cli--processes
54-
command
59+
launch-command
5560
#'ai-code-codex-cli-send-escape
56-
nil
61+
cleanup-fn
5762
nil
5863
ai-code-codex-cli--session-prefix
59-
nil)))
64+
nil
65+
nil
66+
nil
67+
post-start-fn)))
6068

6169
;;;###autoload
6270
(defun ai-code-codex-cli-switch-to-buffer (&optional force-prompt)

‎ai-code-github-copilot-cli.el‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
(require 'ai-code-backends)
1414
(require 'ai-code-backends-infra)
15+
(require 'ai-code-mcp-agent)
1516

1617
(defgroup ai-code-github-copilot-cli nil
1718
"GitHub Copilot CLI integration via `ai-code-backends-infra'."
@@ -61,19 +62,26 @@ With prefix ARG, prompt for CLI args using
6162
ai-code-github-copilot-cli-program-switches
6263
arg
6364
"Copilot"))
64-
(command (plist-get resolved :command)))
65+
(command (plist-get resolved :command))
66+
(mcp-launch (ai-code-mcp-agent-prepare-launch 'github-copilot-cli
67+
working-dir
68+
command))
69+
(launch-command (or (plist-get mcp-launch :command) command))
70+
(cleanup-fn (plist-get mcp-launch :cleanup-fn))
71+
(post-start-fn (plist-get mcp-launch :post-start-fn)))
6572
(ai-code-backends-infra--toggle-or-create-session
6673
working-dir
6774
nil
6875
ai-code-github-copilot-cli--processes
69-
command
76+
launch-command
7077
#'ai-code-github-copilot-cli-send-escape
71-
nil
78+
cleanup-fn
7279
nil
7380
ai-code-github-copilot-cli--session-prefix
7481
nil
7582
ai-code-github-copilot-cli-extra-env-vars
76-
ai-code-github-copilot-cli-multiline-input-sequence)))
83+
ai-code-github-copilot-cli-multiline-input-sequence
84+
post-start-fn)))
7785

7886
;;;###autoload
7987
(defun ai-code-github-copilot-cli-switch-to-buffer (&optional force-prompt)

‎ai-code-mcp-agent.el‎

Lines changed: 128 additions & 0 deletions

0 commit comments

Comments
 (0)