You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We currently implement only the tools/* side of the MCP protocol. The resources/* surface is a spec gap, and it's the obvious next thing to add.
What's missing
resources/list
resources/read
resources/templates/list
resources/templates/read
Resource subscriptions (optional, can defer)
Why it matters
Tools are model-directed: the LLM decides to call them. Resources are client-directed: the user or client attaches content (e.g., @buffer://*scratch* in Claude Desktop). Without resources, the only way for a user to surface Emacs state to the model is to have the model itself call eval-elisp, which:
Is expensive (eval-elisp is destructive+open-world, clients prompt on it)
Is unergonomic (the LLM has to write elisp for a read)
Can't be initiated by the user (they can't proactively attach a buffer)
Resources are read-only by construction, so they add no new security surface.
Concrete resource URIs worth exposing
Initial target set (final list TBD during implementation):
buffer://current - current buffer contents
buffer://{name} - any named buffer (template)
file://{path} - file on disk (template)
org://{file}/headline/{+path} - specific org subtree (template)
emacs://init.el - user's init file
elisp://function/{symbol} - function definition / docstring
project://current/files - project file list
diagnostics://{project} - flycheck/flymake diagnostics (could replace the get-diagnostics tool, or coexist)
Template syntax
Follow the RFC 6570 subset the MCP spec uses:
{var} - simple variable expansion
{+var} - reserved expansion (allows slashes in the value)
mcp-server-lib.el implements this cleanly and is a reasonable reference for parsing/matching logic (not necessarily a source to copy verbatim, but the approach is sound).
API design considerations
Public registration function analogous to mcp-server-register-tool, something like mcp-server-register-resource taking a struct.
We currently implement only the
tools/*side of the MCP protocol. Theresources/*surface is a spec gap, and it's the obvious next thing to add.What's missing
resources/listresources/readresources/templates/listresources/templates/readWhy it matters
Tools are model-directed: the LLM decides to call them. Resources are client-directed: the user or client attaches content (e.g.,
@buffer://*scratch*in Claude Desktop). Without resources, the only way for a user to surface Emacs state to the model is to have the model itself calleval-elisp, which:Resources are read-only by construction, so they add no new security surface.
Concrete resource URIs worth exposing
Initial target set (final list TBD during implementation):
buffer://current- current buffer contentsbuffer://{name}- any named buffer (template)file://{path}- file on disk (template)org://{file}/headline/{+path}- specific org subtree (template)emacs://init.el- user's init fileelisp://function/{symbol}- function definition / docstringproject://current/files- project file listdiagnostics://{project}- flycheck/flymake diagnostics (could replace theget-diagnosticstool, or coexist)Template syntax
Follow the RFC 6570 subset the MCP spec uses:
{var}- simple variable expansion{+var}- reserved expansion (allows slashes in the value)mcp-server-lib.elimplements this cleanly and is a reasonable reference for parsing/matching logic (not necessarily a source to copy verbatim, but the approach is sound).API design considerations
mcp-server-register-tool, something likemcp-server-register-resourcetaking a struct.init.el(tie into the work in Make user-registered tools first-class alongside bundled tools #11 so this doesn't suffer the same filter issues).{...}in the URI (same approach mcp-server-lib uses).