12#include "llvm/Support/JSON.h"
24 llvm::json::ObjectMapper O(V, P);
30 std::unique_ptr<MCPTransport> transport_up,
32 : m_name(std::move(name)), m_version(std::move(version)),
33 m_transport_up(std::move(transport_up)), m_loop(loop) {
39 std::placeholders::_1));
41 std::placeholders::_1));
43 std::placeholders::_1));
45 this, std::placeholders::_1));
47 this, std::placeholders::_1));
53 llvm::Expected<Response> response = it->second(request);
56 response->id = request.
id;
60 return llvm::make_error<MCPError>(
61 llvm::formatv(
"no handler for request: {0}", request.
method).str());
67 it->second(notification);
75 m_tools[tool->GetName()] = std::move(tool);
79 std::unique_ptr<ResourceProvider> resource_provider) {
80 if (!resource_provider)
101 response.
result = std::move(result);
109 for (
const auto &tool :
m_tools)
110 result.
tools.emplace_back(tool.second->GetDefinition());
112 response.
result = std::move(result);
121 return llvm::createStringError(
"no tool parameters");
123 json::Path::Root root(
"params");
125 return root.getError();
127 llvm::StringRef tool_name = params.
name;
128 if (tool_name.empty())
129 return llvm::createStringError(
"no tool name");
131 auto it =
m_tools.find(tool_name);
133 return llvm::createStringError(llvm::formatv(
"no tool \"{0}\"", tool_name));
139 llvm::Expected<CallToolResult> text_result = it->second->Call(tool_args);
141 return text_result.takeError();
152 for (std::unique_ptr<ResourceProvider> &resource_provider_up :
154 for (
const Resource &resource : resource_provider_up->GetResources())
157 response.
result = std::move(result);
166 return llvm::createStringError(
"no resource parameters");
169 json::Path::Root root(
"params");
171 return root.getError();
173 llvm::StringRef uri_str = params.
uri;
175 return llvm::createStringError(
"no resource uri");
177 for (std::unique_ptr<ResourceProvider> &resource_provider_up :
179 llvm::Expected<ReadResourceResult> result =
180 resource_provider_up->ReadResource(uri_str);
182 llvm::consumeError(result.takeError());
186 return result.takeError();
189 response.
result = std::move(*result);
193 return make_error<MCPError>(
194 llvm::formatv(
"no resource handler for uri: {0}", uri_str).str(),
210 return handle.takeError();
216 return llvm::Error::success();
220 auto SendResponse = [
this](
const Response &response) {
225 llvm::Expected<Response> response =
Handle(request);
227 return SendResponse(*response);
230 llvm::handleAllErrors(
231 response.takeError(),
232 [&](
const MCPError &err) { protocol_error = err.toProtocolError(); },
233 [&](
const llvm::ErrorInfoBase &err) {
234 protocol_error.code = MCPError::kInternalError;
235 protocol_error.message = err.message();
238 error_response.
id = request.
id;
239 error_response.
result = std::move(protocol_error);
240 SendResponse(error_response);
static llvm::raw_ostream & error(Stream &strm)
void AddPendingCallback(const Callback &callback)
virtual void RequestTermination()
bool Fail() const
Test for error condition.
static constexpr int64_t kResourceNotFound
std::function< void(const Notification &)> NotificationHandler
llvm::Expected< Response > ToolsCallHandler(const Request &)
const std::string m_version
void AddTool(std::unique_ptr< Tool > tool)
void AddResourceProvider(std::unique_ptr< ResourceProvider > resource_provider)
lldb_private::MainLoop & m_loop
Server(std::string name, std::string version, std::unique_ptr< MCPTransport > transport_up, lldb_private::MainLoop &loop)
llvm::StringMap< std::unique_ptr< Tool > > m_tools
std::vector< std::unique_ptr< ResourceProvider > > m_resource_providers
llvm::StringMap< NotificationHandler > m_notification_handlers
void AddRequestHandlers()
llvm::StringMap< RequestHandler > m_request_handlers
void OnError(llvm::Error) override
Called when an error occurs while reading from the transport.
llvm::Expected< Response > ResourcesListHandler(const Request &)
llvm::Expected< Response > ResourcesReadHandler(const Request &)
llvm::Expected< Response > Handle(const Request &request)
llvm::Expected< Response > ToolsListHandler(const Request &)
void AddRequestHandler(llvm::StringRef method, RequestHandler handler)
std::unique_ptr< MCPTransport > m_transport_up
std::function< llvm::Expected< Response >(const Request &)> RequestHandler
void Received(const Request &) override
void OnClosed() override
Called on EOF or client disconnect.
ServerCapabilities GetCapabilities()
void AddNotificationHandler(llvm::StringRef method, NotificationHandler handler)
llvm::Expected< Response > InitializeHandler(const Request &)
llvm::json::Value toJSON(const Request &)
std::variant< std::monostate, llvm::json::Value > ToolArguments
static llvm::StringLiteral kProtocolVersion
bool fromJSON(const llvm::json::Value &, Request &, llvm::json::Path)
std::string name
Intended for programmatic or logical use, but used as a display name in past specs or fallback (if ti...
After receiving an initialize request from the client, the server sends this response.
std::string protocolVersion
The version of the Model Context Protocol that the server wants to use.
ServerCapabilities capabilities
Implementation serverInfo
The server’s response to a resources/list request from the client.
std::vector< Resource > resources
A notification which does not expect a response.
std::string method
The method to be invoked.
Sent from the client to the server, to read a specific resource URI.
std::string uri
The URI of the resource to read.
A request that expects a response.
std::optional< llvm::json::Value > params
The method's params.
std::string method
The method to be invoked.
A known resource that the server is capable of reading.
A response to a request, either an error or a result.
std::variant< Error, llvm::json::Value > result
The result of the request, either an Error or the JSON value of the response.
Capabilities that a server may support.
bool supportsResourcesList
Information about this instance of lldb's MCP server for lldb-mcp to use to coordinate connecting an ...
std::string connection_uri