mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
handle mcp-session-id.
This commit is contained in:
@@ -1,26 +1,53 @@
|
||||
set -v
|
||||
|
||||
hostname=localhost
|
||||
port_no=8086
|
||||
entrypoint=mcp
|
||||
|
||||
# "protocolVersion": "2025-03-26",
|
||||
# "protocolVersion": "2024-11-05",
|
||||
# -H "Host: localhost:8086" \
|
||||
# -H "Connection:Keep-Alive" \
|
||||
# -H "Sec-Fetch-Mode: cors" \
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json,text/event-stream" \
|
||||
-D response_headers.txt \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "initialize",
|
||||
"params": {
|
||||
"protocolVersion": "2025-03-26",
|
||||
"protocolVersion": "2024-11-05",
|
||||
"capabilities": {
|
||||
"tools": {}
|
||||
},
|
||||
"clientInfo": {
|
||||
"name": "curl-client",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
},
|
||||
"id": 1
|
||||
"id": 0
|
||||
}' \
|
||||
http://localhost:8085/mcp
|
||||
http://${hostname}:${port_no}/${entrypoint}
|
||||
|
||||
curl -X POST \
|
||||
grep -i "mcp-session-id" response_headers.txt | cut -d' ' -f2 > sess_id.txt
|
||||
|
||||
sleep 1
|
||||
|
||||
sess_id=`cat sess_id.txt`
|
||||
sess_header="Mcp-Session-Id: ${sess_id}"
|
||||
echo $sess_header
|
||||
|
||||
curl -v -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json,text/event-stream" \
|
||||
-H "$sess_header" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "notifications/initialized"
|
||||
}' \
|
||||
http://localhost:8085/mcp
|
||||
http://${hostname}:${port_no}/${entrypoint}
|
||||
|
||||
#curl -X POST \
|
||||
# -H "Content-Type: application/json" \
|
||||
# -d '{"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"claude-ai","version":"0.1.0"}},"jsonrpc":"2.0","id":0}' \
|
||||
# http://localhost:8085/mcp
|
||||
|
||||
@@ -27,11 +27,10 @@
|
||||
// TODO
|
||||
//
|
||||
// [ ] Roots(from Protocol revision 2025-06-18)
|
||||
//
|
||||
// Server notification
|
||||
//
|
||||
// [ ] resources/list_changed
|
||||
// [ ] tools/list_changed
|
||||
// [ ] Use mcp-session-id in resources and tools.
|
||||
// [ ] Server notification
|
||||
// [ ] resources/list_changed
|
||||
// [ ] tools/list_changed
|
||||
|
||||
namespace tinyusdz {
|
||||
namespace tydra {
|
||||
@@ -79,7 +78,33 @@ enum JsonRpcErrorCode {
|
||||
};
|
||||
|
||||
// Method handler function type
|
||||
using MethodHandler = std::function<nlohmann::json(const nlohmann::json&, std::string &)>;
|
||||
// <params, sess_id, err>
|
||||
using MethodHandler = std::function<nlohmann::json(const nlohmann::json&, const std::string &, std::string &)>;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
bool has_header(const struct mg_request_info *ri, const char *name) {
|
||||
for (int i = 0; i < ri->num_headers; i++) {
|
||||
DCOUT("header" + std::string(ri->http_headers[i].name));
|
||||
if (strcmp(ri->http_headers[i].name, name) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string get_header_value(const struct mg_request_info *ri, const char *name) {
|
||||
for (int i = 0; i < ri->num_headers; i++) {
|
||||
if (strcmp(ri->http_headers[i].name, name) == 0) {
|
||||
return std::string(ri->http_headers[i].value);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
class MCPServer::Impl {
|
||||
public:
|
||||
@@ -122,7 +147,7 @@ class MCPServer::Impl {
|
||||
static int mcp_handler(struct mg_connection *conn, void *user_data);
|
||||
|
||||
// Process JSON-RPC request
|
||||
JsonRpcResponse process_request(const JsonRpcRequest& request);
|
||||
JsonRpcResponse process_request(const JsonRpcRequest& request, const std::string &sess_id);
|
||||
|
||||
// Parse JSON-RPC request from string
|
||||
JsonRpcRequest parse_request(const std::string& json_str);
|
||||
@@ -143,6 +168,13 @@ int MCPServer::Impl::mcp_handler(struct mg_connection *conn, void *user_data) {
|
||||
const struct mg_request_info *request_info = mg_get_request_info(conn);
|
||||
|
||||
DCOUT("req_method " << request_info->request_method);
|
||||
|
||||
std::string mcp_sess_id;
|
||||
// TODO: Support Mcp-Session-Id?
|
||||
if (has_header(request_info, "mcp-session-id")) {
|
||||
mcp_sess_id = get_header_value(request_info, "mcp-session-id");
|
||||
DCOUT("mcp-session-id " << mcp_sess_id);
|
||||
}
|
||||
|
||||
// Handle POST requests for JSON-RPC
|
||||
if (strcmp(request_info->request_method, "POST") == 0) {
|
||||
@@ -158,7 +190,7 @@ int MCPServer::Impl::mcp_handler(struct mg_connection *conn, void *user_data) {
|
||||
|
||||
// Parse and process JSON-RPC request
|
||||
JsonRpcRequest rpc_request = server->parse_request(body);
|
||||
JsonRpcResponse rpc_response = server->process_request(rpc_request);
|
||||
JsonRpcResponse rpc_response = server->process_request(rpc_request, mcp_sess_id);
|
||||
|
||||
if (rpc_request.is_notification()) {
|
||||
// Return 202
|
||||
@@ -246,7 +278,7 @@ JsonRpcRequest MCPServer::Impl::parse_request(const std::string& json_str) {
|
||||
return request;
|
||||
}
|
||||
|
||||
JsonRpcResponse MCPServer::Impl::process_request(const JsonRpcRequest& request) {
|
||||
JsonRpcResponse MCPServer::Impl::process_request(const JsonRpcRequest& request, const std::string &sess_id) {
|
||||
// Validate JSON-RPC version
|
||||
if (request.jsonrpc != "2.0") {
|
||||
return create_error_response(INVALID_REQUEST, "Invalid JSON-RPC version", request.id);
|
||||
@@ -260,7 +292,7 @@ JsonRpcResponse MCPServer::Impl::process_request(const JsonRpcRequest& request)
|
||||
|
||||
// Execute method handler
|
||||
std::string err;
|
||||
nlohmann::json result = handler_it->second(request.params, err);
|
||||
nlohmann::json result = handler_it->second(request.params, sess_id, err);
|
||||
|
||||
JsonRpcResponse response;
|
||||
|
||||
@@ -293,7 +325,8 @@ bool MCPServer::Impl::init(int port, const std::string &host) {
|
||||
// TODO
|
||||
(void)host;
|
||||
|
||||
register_method("ping", [](const nlohmann::json& params, std::string &err) -> nlohmann::json {
|
||||
register_method("ping", [](const nlohmann::json& params, const std::string &sess_id, std::string &err) -> nlohmann::json {
|
||||
(void)sess_id;
|
||||
(void)err;
|
||||
(void)params;
|
||||
|
||||
@@ -303,7 +336,8 @@ bool MCPServer::Impl::init(int port, const std::string &host) {
|
||||
});
|
||||
|
||||
// Register MCP initialize method
|
||||
register_method("initialize", [](const nlohmann::json& params, std::string &err) -> nlohmann::json {
|
||||
register_method("initialize", [](const nlohmann::json& params, const std::string sess_id, std::string &err) -> nlohmann::json {
|
||||
(void)sess_id;
|
||||
(void)err;
|
||||
// Extract client info if provided
|
||||
std::string client_name = "unknown";
|
||||
@@ -333,7 +367,8 @@ bool MCPServer::Impl::init(int port, const std::string &host) {
|
||||
};
|
||||
});
|
||||
|
||||
register_method("notifications/cancelled",[](const nlohmann::json ¶ms, std::string &err) -> nlohmann::json {
|
||||
register_method("notifications/cancelled",[](const nlohmann::json ¶ms, const std::string &sess_id, std::string &err) -> nlohmann::json {
|
||||
(void)sess_id;
|
||||
|
||||
if (!params.contains("requestId")) {
|
||||
err = "`requestId` is missing in params.";
|
||||
@@ -346,10 +381,11 @@ bool MCPServer::Impl::init(int port, const std::string &host) {
|
||||
return {};
|
||||
});
|
||||
|
||||
register_method("resources/list",[](const nlohmann::json ¶ms, std::string &err) -> nlohmann::json {
|
||||
register_method("resources/list",[](const nlohmann::json ¶ms, const std::string &sess_id, std::string &err) -> nlohmann::json {
|
||||
|
||||
(void)err;
|
||||
(void)params;
|
||||
(void)sess_id;
|
||||
|
||||
nlohmann::json j;
|
||||
mcp::GetResourcesList(j);
|
||||
@@ -358,10 +394,11 @@ bool MCPServer::Impl::init(int port, const std::string &host) {
|
||||
|
||||
});
|
||||
|
||||
register_method("resources/read",[](const nlohmann::json ¶ms, std::string &err) -> nlohmann::json {
|
||||
register_method("resources/read",[](const nlohmann::json ¶ms, const std::string &sess_id, std::string &err) -> nlohmann::json {
|
||||
|
||||
(void)err;
|
||||
(void)params;
|
||||
(void)sess_id;
|
||||
|
||||
if (!params.contains("uri")) {
|
||||
err = "`name` is missing in params.";
|
||||
@@ -379,10 +416,11 @@ bool MCPServer::Impl::init(int port, const std::string &host) {
|
||||
|
||||
});
|
||||
|
||||
register_method("tools/list",[](const nlohmann::json ¶ms, std::string &err) -> nlohmann::json {
|
||||
register_method("tools/list",[](const nlohmann::json ¶ms, const std::string &sess_id, std::string &err) -> nlohmann::json {
|
||||
|
||||
(void)err;
|
||||
(void)params;
|
||||
(void)sess_id;
|
||||
|
||||
nlohmann::json j;
|
||||
mcp::GetToolsList(j);
|
||||
@@ -391,8 +429,9 @@ bool MCPServer::Impl::init(int port, const std::string &host) {
|
||||
|
||||
});
|
||||
|
||||
register_method("tools/call",[this](const nlohmann::json ¶ms, std::string &err) -> nlohmann::json {
|
||||
register_method("tools/call",[this](const nlohmann::json ¶ms, const std::string &sess_id, std::string &err) -> nlohmann::json {
|
||||
|
||||
(void)sess_id;
|
||||
|
||||
if (!params.contains("name")) {
|
||||
err = "`name` is missing in params.";
|
||||
@@ -415,10 +454,11 @@ bool MCPServer::Impl::init(int port, const std::string &host) {
|
||||
|
||||
});
|
||||
|
||||
register_method("notifications/initialized", [](const nlohmann::json& params, std::string &err) -> nlohmann::json {
|
||||
register_method("notifications/initialized", [](const nlohmann::json& params, const std::string &sess_id, std::string &err) -> nlohmann::json {
|
||||
// no response required
|
||||
(void)params;
|
||||
(void)err;
|
||||
(void)sess_id;
|
||||
|
||||
// Return server capabilities
|
||||
return nlohmann::json::object();
|
||||
|
||||
Reference in New Issue
Block a user