Skip to content

Commit 2d08cb5

Browse files
mcp-v2 (#573)
* mcp-v2 Summary: - MCP server and postgres server run concurrently. - Added robot test `Concurrent psql and MCP HTTP Server Query Tool`. * - Corrected robot test. * - OS `psql` adaptability.
1 parent bd1e9ad commit 2d08cb5

File tree

4 files changed

+83
-33
lines changed

4 files changed

+83
-33
lines changed

internal/stackql/cmd/mcp.go

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/stackql/any-sdk/pkg/logging"
2525
"github.com/stackql/stackql/internal/stackql/acid/tsm_physio"
2626
"github.com/stackql/stackql/internal/stackql/entryutil"
27+
"github.com/stackql/stackql/internal/stackql/handler"
2728
"github.com/stackql/stackql/internal/stackql/iqlerror"
2829
"github.com/stackql/stackql/internal/stackql/mcpbackend"
2930
"github.com/stackql/stackql/pkg/mcp_server"
@@ -52,35 +53,42 @@ var mcpSrvCmd = &cobra.Command{
5253
handlerCtx, err := entryutil.BuildHandlerContext(runtimeCtx, nil, queryCache, inputBundle, false)
5354
iqlerror.PrintErrorAndExitOneIfError(err)
5455
iqlerror.PrintErrorAndExitOneIfNil(handlerCtx, "handler context is unexpectedly nil")
55-
var config mcp_server.Config
56-
json.Unmarshal([]byte(mcpConfig), &config) //nolint:errcheck // TODO: investigate
57-
config.Server.Transport = mcpServerType
58-
var isReadOnly bool
59-
if config.Server.IsReadOnly != nil {
60-
isReadOnly = *config.Server.IsReadOnly
56+
if mcpServerType == "" {
57+
mcpServerType = "http"
6158
}
62-
orchestrator, orchestratorErr := tsm_physio.NewOrchestrator(handlerCtx)
63-
iqlerror.PrintErrorAndExitOneIfError(orchestratorErr)
64-
iqlerror.PrintErrorAndExitOneIfNil(orchestrator, "orchestrator is unexpectedly nil")
65-
// handlerCtx.SetTSMOrchestrator(orchestrator)
66-
backend, backendErr := mcpbackend.NewStackqlMCPBackendService(
67-
isReadOnly,
68-
orchestrator,
69-
handlerCtx,
70-
logging.GetLogger(),
71-
)
72-
iqlerror.PrintErrorAndExitOneIfError(backendErr)
73-
iqlerror.PrintErrorAndExitOneIfNil(backend, "mcp backend is unexpectedly nil")
74-
75-
server, serverErr := mcp_server.NewAgnosticBackendServer(
76-
backend,
77-
&config,
78-
logging.GetLogger(),
79-
)
80-
// server, serverErr := mcp_server.NewExampleHTTPBackendServer(
81-
// logging.GetLogger(),
82-
// )
83-
iqlerror.PrintErrorAndExitOneIfError(serverErr)
84-
server.Start(context.Background()) //nolint:errcheck // TODO: investigate
59+
runMCPServer(handlerCtx)
8560
},
8661
}
62+
63+
func runMCPServer(handlerCtx handler.HandlerContext) {
64+
var config mcp_server.Config
65+
json.Unmarshal([]byte(mcpConfig), &config) //nolint:errcheck // TODO: investigate
66+
config.Server.Transport = mcpServerType
67+
var isReadOnly bool
68+
if config.Server.IsReadOnly != nil {
69+
isReadOnly = *config.Server.IsReadOnly
70+
}
71+
orchestrator, orchestratorErr := tsm_physio.NewOrchestrator(handlerCtx)
72+
iqlerror.PrintErrorAndExitOneIfError(orchestratorErr)
73+
iqlerror.PrintErrorAndExitOneIfNil(orchestrator, "orchestrator is unexpectedly nil")
74+
// handlerCtx.SetTSMOrchestrator(orchestrator)
75+
backend, backendErr := mcpbackend.NewStackqlMCPBackendService(
76+
isReadOnly,
77+
orchestrator,
78+
handlerCtx,
79+
logging.GetLogger(),
80+
)
81+
iqlerror.PrintErrorAndExitOneIfError(backendErr)
82+
iqlerror.PrintErrorAndExitOneIfNil(backend, "mcp backend is unexpectedly nil")
83+
84+
server, serverErr := mcp_server.NewAgnosticBackendServer(
85+
backend,
86+
&config,
87+
logging.GetLogger(),
88+
)
89+
// server, serverErr := mcp_server.NewExampleHTTPBackendServer(
90+
// logging.GetLogger(),
91+
// )
92+
iqlerror.PrintErrorAndExitOneIfError(serverErr)
93+
server.Start(context.Background()) //nolint:errcheck // TODO: investigate
94+
}

internal/stackql/cmd/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ func init() {
199199
rootCmd.AddCommand(srvCmd)
200200
rootCmd.AddCommand(mcpSrvCmd)
201201

202-
mcpSrvCmd.PersistentFlags().StringVar(&mcpConfig, "mcp.config", "{}", "MCP server config file path (YAML or JSON)")
203-
mcpSrvCmd.PersistentFlags().StringVar(&mcpServerType, "mcp.server.type", "http", "MCP server type (http or stdio for now)")
202+
rootCmd.PersistentFlags().StringVar(&mcpConfig, "mcp.config", "{}", "MCP server config file path (YAML or JSON)")
203+
rootCmd.PersistentFlags().StringVar(&mcpServerType, "mcp.server.type", "", "MCP server type (http or stdio for now)")
204204
}
205205

206206
func mergeConfigFromFile(runtimeCtx *dto.RuntimeCtx, flagSet pflag.FlagSet) {

internal/stackql/cmd/srv.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ var srvCmd = &cobra.Command{
4848
sbe := driver.NewStackQLDriverFactory(handlerCtx, runtimeCtx.PGSrvIsDebugNoticesEnabled)
4949
server, err := psqlwire.MakeWireServer(sbe, runtimeCtx)
5050
iqlerror.PrintErrorAndExitOneIfError(err)
51+
if mcpServerType != "" {
52+
go runMCPServer(handlerCtx.Clone()) //nolint:errcheck // TODO: investigate
53+
}
5154
server.Serve() //nolint:errcheck // TODO: investigate
5255
},
5356
}

test/robot/functional/mcp.robot

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Resource ${CURDIR}${/}stackql.resource
33

44

55
*** Keywords ***
6-
Start MCP HTTP Server
6+
Start MCP Servers
77
Pass Execution If "%{IS_SKIP_MCP_TEST=false}" == "true" Some platforms do not have the MCP client available
88
Start Process ${STACKQL_EXE}
99
... mcp
@@ -15,10 +15,22 @@ Start MCP HTTP Server
1515
... \-\-auth
1616
... ${AUTH_CFG_STR}
1717
... \-\-tls.allowInsecure
18+
Start Process ${STACKQL_EXE}
19+
... srv
20+
... \-\-mcp.server.type\=http
21+
... \-\-mcp.config
22+
... {"server": {"transport": "http", "address": "127.0.0.1:9913"} }
23+
... \-\-registry
24+
... ${REGISTRY_NO_VERIFY_CFG_JSON_STR}
25+
... \-\-auth
26+
... ${AUTH_CFG_STR}
27+
... \-\-tls.allowInsecure
28+
... \-\-pgsrv.port
29+
... 5665
1830
Sleep 5s
1931

2032
*** Settings ***
21-
Suite Setup Start MCP HTTP Server
33+
Suite Setup Start MCP Servers
2234

2335

2436
*** Test Cases ***
@@ -120,3 +132,30 @@ MCP HTTP Server Query Tool
120132
Should Contain ${result.stdout} cloudkms.googleapis.com
121133
Should Be Equal As Integers ${result.rc} 0
122134

135+
136+
Concurrent psql and MCP HTTP Server Query Tool
137+
Pass Execution If "%{IS_SKIP_MCP_TEST=false}" == "true" Some platforms do not have the MCP client available
138+
Sleep 5s
139+
${mcp_client_result}= Run Process ${STACKQL_MCP_CLIENT_EXE}
140+
... exec
141+
... \-\-client\-type\=http
142+
... \-\-url\=http://127.0.0.1:9913
143+
... \-\-exec.action query_v2
144+
... \-\-exec.args {"sql": "SELECT assetType, count(*) as asset_count FROM google.cloudasset.assets WHERE parentType \= 'projects' and parent \= 'testing-project' GROUP BY assetType order by count(*) desc, assetType desc;"}
145+
... stdout=${CURDIR}${/}tmp${/}MCP-HTTP-Server-Query-Tool.txt
146+
... stderr=${CURDIR}${/}tmp${/}MCP-HTTP-Server-Query-Tool-stderr.txt
147+
Should Contain ${mcp_client_result.stdout} cloudkms.googleapis.com
148+
Should Be Equal As Integers ${mcp_client_result.rc} 0
149+
${posixInput} = Catenate
150+
... "${PSQL_EXE}" -d postgres://stackql:stackql@127.0.0.1:5665 -c
151+
... "SELECT assetType, count(*) as asset_count FROM google.cloudasset.assets WHERE parentType = 'projects' and parent = 'testing-project' GROUP BY assetType order by count(*) desc, assetType desc;"
152+
${windowsInput} = Catenate
153+
... & ${posixInput}
154+
${input} = Set Variable If "${IS_WINDOWS}" == "1" ${windowsInput} ${posixInput}
155+
${shellExe} = Set Variable If "${IS_WINDOWS}" == "1" powershell sh
156+
${psql_client_result}= Run Process
157+
... ${shellExe} \-c ${input}
158+
... stdout=${CURDIR}${/}tmp${/}Concurrent-psql-and-MCP-HTTP-Server-Query-Tool.txt
159+
... stderr=${CURDIR}${/}tmp${/}Concurrent-psql-and-MCP-HTTP-Server-Query-Tool-stderr.txt
160+
Should Contain ${psql_client_result.stdout} cloudkms.googleapis.com
161+
Should Be Equal As Integers ${psql_client_result.rc} 0

0 commit comments

Comments
 (0)