|
1 | | -# CopilotChat Integration <Badge type="warning" text="Draft"/> |
| 1 | +# CopilotChat Integration |
2 | 2 |
|
3 | | -[CopilotChat.nvim](https://github.com/CopilotC-Nvim/CopilotChat.nvim) supports function calling which is currently in [draft](https://github.com/CopilotC-Nvim/CopilotChat.nvim/pull/1029). To integrate MCP Hub with CopilotChat we need to use the `tools` branch of CopilotChat as shown below: |
| 3 | +Add MCP capabilities to [CopilotChat.nvim](https://github.com/CopilotC-Nvim/CopilotChat.nvim) by adding it as an extension. CopilotChat now has native function-calling support, making it easy to integrate MCP tools and resources. |
4 | 4 |
|
5 | | -> [!WARNING] |
6 | | -> Please note that CopilotChat function-calling support is available as a [Draft PR](https://github.com/CopilotC-Nvim/CopilotChat.nvim/pull/1029). |
| 5 | +## Features |
7 | 6 |
|
8 | | -## Install CopilotChat |
| 7 | +- **Tool Integration**: Register MCP tools as CopilotChat functions with proper schemas |
| 8 | +- **Resource Integration**: Register MCP resources as CopilotChat functions for easy access |
| 9 | +- **Server Groups**: Functions are organized by MCP server name for better organization |
| 10 | +- **Real-time Updates**: Automatic updates in CopilotChat when MCP servers change |
9 | 11 |
|
10 | | -```lua |
11 | | -{ |
12 | | - "deathbeam/CopilotChat.nvim", |
13 | | - dependencies = { |
14 | | - { "zbirenbaum/copilot.lua" }, |
15 | | - { "nvim-lua/plenary.nvim", branch = "master" }, -- for curl, log and async functions |
16 | | - }, |
17 | | - branch = "tools", |
18 | | - build = "make tiktoken", -- Only on MacOS or Linux |
19 | | -} |
20 | | -``` |
| 12 | +## Setup |
21 | 13 |
|
22 | | -## Integrate MCP Hub |
| 14 | +#### Enable CopilotChat Extension |
23 | 15 |
|
24 | | -After the `setup()` of CopilotChat is called, add the following code. Please see the [draft PR](https://github.com/CopilotC-Nvim/CopilotChat.nvim/pull/1029) for more information. |
| 16 | +Add CopilotChat as an extension in your MCPHub configuration: |
25 | 17 |
|
26 | 18 | ```lua |
27 | | -local chat = require("CopilotChat") |
28 | | -chat.setup() |
29 | | - |
30 | | -local mcp = require("mcphub") |
31 | | -mcp.on({ "servers_updated", "tool_list_changed", "resource_list_changed" }, function() |
32 | | - local hub = mcp.get_hub_instance() |
33 | | - if not hub then |
34 | | - return |
35 | | - end |
36 | | - |
37 | | - local async = require("plenary.async") |
38 | | - local call_tool = async.wrap(function(server, tool, input, callback) |
39 | | - hub:call_tool(server, tool, input, { |
40 | | - callback = function(res, err) |
41 | | - callback(res, err) |
42 | | - end, |
43 | | - }) |
44 | | - end, 4) |
45 | | - |
46 | | - local access_resource = async.wrap(function(server, uri, callback) |
47 | | - hub:access_resource(server, uri, { |
48 | | - callback = function(res, err) |
49 | | - callback(res, err) |
50 | | - end, |
51 | | - }) |
52 | | - end, 3) |
53 | | - |
54 | | - for name, tool in pairs(chat.config.functions) do |
55 | | - if tool.id and tool.id:sub(1, 3) == "mcp" then |
56 | | - chat.config.functions[name] = nil |
57 | | - end |
58 | | - end |
59 | | - local resources = hub:get_resources() |
60 | | - for _, resource in ipairs(resources) do |
61 | | - local name = resource.name:lower():gsub(" ", "_"):gsub(":", "") |
62 | | - chat.config.functions[name] = { |
63 | | - id = "mcp:" .. resource.server_name .. ":" .. name, |
64 | | - uri = resource.uri, |
65 | | - description = type(resource.description) == "string" and resource.description or "", |
66 | | - resolve = function() |
67 | | - local res, err = access_resource(resource.server_name, resource.uri) |
68 | | - if err then |
69 | | - error(err) |
70 | | - end |
71 | | - |
72 | | - res = res or {} |
73 | | - local result = res.result or {} |
74 | | - local content = result.contents or {} |
75 | | - local out = {} |
76 | | - |
77 | | - for _, message in ipairs(content) do |
78 | | - if message.text then |
79 | | - table.insert(out, { |
80 | | - uri = message.uri, |
81 | | - data = message.text, |
82 | | - mimetype = message.mimeType, |
83 | | - }) |
84 | | - end |
85 | | - end |
86 | | - |
87 | | - return out |
88 | | - end, |
89 | | - } |
90 | | - end |
91 | | - |
92 | | - local tools = hub:get_tools() |
93 | | - for _, tool in ipairs(tools) do |
94 | | - chat.config.functions[tool.name] = { |
95 | | - id = "mcp:" .. tool.server_name .. ":" .. tool.name, |
96 | | - group = tool.server_name, |
97 | | - description = tool.description, |
98 | | - schema = tool.inputSchema, |
99 | | - resolve = function(input) |
100 | | - local res, err = call_tool(tool.server_name, tool.name, input) |
101 | | - if err then |
102 | | - error(err) |
103 | | - end |
104 | | - |
105 | | - res = res or {} |
106 | | - local result = res.result or {} |
107 | | - local content = result.content or {} |
108 | | - local out = {} |
109 | | - |
110 | | - for _, message in ipairs(content) do |
111 | | - if message.type == "text" then |
112 | | - table.insert(out, { |
113 | | - data = message.text, |
114 | | - }) |
115 | | - elseif message.type == "resource" and message.resource and message.resource.text then |
116 | | - table.insert(out, { |
117 | | - uri = message.resource.uri, |
118 | | - data = message.resource.text, |
119 | | - mimetype = message.resource.mimeType, |
120 | | - }) |
121 | | - end |
122 | | - end |
123 | | - |
124 | | - return out |
125 | | - end, |
126 | | - } |
127 | | - end |
128 | | -end) |
| 19 | +require("mcphub").setup({ |
| 20 | + extensions = { |
| 21 | + copilotchat = { |
| 22 | + enabled = true, |
| 23 | + convert_tools_to_functions = true, -- Convert MCP tools to CopilotChat functions |
| 24 | + convert_resources_to_functions = true, -- Convert MCP resources to CopilotChat functions |
| 25 | + add_mcp_prefix = false, -- Add "mcp_" prefix to function names |
| 26 | + } |
| 27 | + } |
| 28 | +}) |
129 | 29 | ``` |
130 | 30 |
|
| 31 | +#### Configuration Options |
| 32 | + |
| 33 | +- **`convert_tools_to_functions`**: When `true`, all MCP tools are registered as CopilotChat functions |
| 34 | +- **`convert_resources_to_functions`**: When `true`, all MCP resources are registered as CopilotChat functions |
| 35 | +- **`add_mcp_prefix`**: When `true`, adds "mcp_" prefix to all function names (e.g., `mcp_github__get_issue`) |
| 36 | + |
131 | 37 | ## Usage |
132 | 38 |
|
133 | | -#### MCP Servers As Tools |
| 39 | +### MCP Tools |
| 40 | + |
| 41 | +When `convert_tools_to_functions = true`, all MCP tools become available as CopilotChat functions. Functions are automatically organized by server name, making it easy to see all tools from a specific MCP server. Tool names follow the pattern `server_name__tool_name`: |
| 42 | + |
| 43 | +**Examples:** |
| 44 | +- `@neovim__read_file` - Read a file using the neovim server |
| 45 | +- `@github__create_issue` - Create a GitHub issue |
| 46 | +- `@fetch__fetch` - Fetch web content |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | +### MCP Resources |
134 | 51 |
|
135 | | -You can type `@` in the chat to see all the available tools in CopilotChat. CopilotChat allows us to add all the tools of a MCP server as a tool group as well as the individual tools. For e.g `> @neovim` will add all the tools of Neovim MCP server to the chat. The `>` at the start makes it sticky which means the tools will be sent with all user prompts. You can also just add a specific tool from Neovim server by selecting from the group. |
| 52 | +You can use `#` to access MCP resources as variables in CopilotChat. In addition, when `convert_resources_to_functions = true`, all MCP resources will also be available as CopilotChat functions: |
136 | 53 |
|
137 | | - |
| 54 | +**Examples:** |
| 55 | +- `#neovim__Buffer` - Access current buffer content |
| 56 | +- `@neovim__Buffer` - Get current buffer content (as a function) |
138 | 57 |
|
139 | | - |
| 58 | + |
140 | 59 |
|
141 | | -#### MCP Resources As Variables |
142 | 60 |
|
143 | | -Resources from MCP servers will also be available as CopilotChat variables `#`. |
144 | 61 |
|
145 | | - |
| 62 | +## Example Workflow |
146 | 63 |
|
| 64 | +1. **Start CopilotChat** and type `@` to see available functions |
| 65 | +2. **Select MCP functions** from your connected servers |
| 66 | +3. **Use tools**: `@github__create_issue Fix the navigation bug` |
| 67 | +4. **Access resources**: `@neovim__current_buffer Show me the current file content` |
| 68 | +5. **Organize by server**: Browse functions grouped by MCP server |
147 | 69 |
|
| 70 | + |
0 commit comments