Context
Sub-issue of #207 — Phase 3(A): Dedicated subcommands for calling individual ql-mcp server primitives, with shared Go library code reused by the integration test runner.
Depends on: #217 (Phase 2 — Go binary and integration test runner)
Problem
After Phase 2, the ql-mcp-client Go binary can run integration tests and list registered primitives, but there is no way to call an individual prompt, resource, or tool from the CLI. Users who want to exercise a specific ql-mcp server primitive must either write ad-hoc scripts or use the integration test runner indirectly.
Additionally, the integration test runner (client/internal/testing/runner.go) contains its own inline logic for calling MCP primitives. This should be refactored so that the test runner and the new use subcommands share the same Go library code for discovery, invocation, and response formatting.
Requirements
New use subcommands
Shared primitive-calling Go library
Integration test runner refactoring
Output formatting
Example usage
# Call a tool with arguments
ql-mcp-client use tool sarif_list_rules --arg sarifPath=/path/to/results.sarif
# Read a resource
ql-mcp-client use resource codeql://server/tools
# Get a prompt with arguments
ql-mcp-client use prompt explain_codeql_query \
--arg queryPath=/path/to/query.ql \
--arg databasePath=/path/to/db \
--arg language=javascript
# List available tools (already exists from Phase 2, included for completeness)
ql-mcp-client list tools
# JSON output (default)
ql-mcp-client use tool codeql_resolve_languages --format json
# Human-readable output
ql-mcp-client use tool codeql_resolve_languages --format text
Architecture
client/internal/mcp/
├── client.go # MCP client connection (Phase 2)
├── client_test.go # Unit tests (Phase 2)
├── primitives.go # NEW: Shared primitive-calling functions
└── primitives_test.go # NEW: Unit tests
client/cmd/
├── use.go # NEW: `use` parent subcommand
├── use_tool.go # NEW: `use tool` subcommand
├── use_resource.go # NEW: `use resource` subcommand
├── use_prompt.go # NEW: `use prompt` subcommand
├── use_test.go # NEW: Unit tests for `use` subcommands
└── ...
client/internal/testing/
├── runner.go # MODIFIED: Refactored to use internal/mcp/primitives
└── runner_test.go # MODIFIED: Updated tests
Key design constraint
The client/internal/mcp/primitives.go library is the single source of truth for calling MCP primitives. Both the use subcommands and the integration test runner must use this library — no separate implementations.
Acceptance criteria
ql-mcp-client use tool <name> --arg k=v calls the tool and prints the response
ql-mcp-client use resource <uri> reads the resource and prints the content
ql-mcp-client use prompt <name> --arg k=v gets the prompt and prints the messages
- All three subcommands support
--format json|text|markdown
- The integration test runner in
client/internal/testing/runner.go uses client/internal/mcp/primitives.go for all MCP calls
- No duplicated MCP invocation logic between the
use subcommands and the test runner
go test ./... passes all Go unit tests in client/
- All existing integration test fixtures still pass with the refactored test runner
npm run build-and-test passes end-to-end
Files changed
Added
client/internal/mcp/primitives.go
client/internal/mcp/primitives_test.go
client/cmd/use.go
client/cmd/use_tool.go
client/cmd/use_resource.go
client/cmd/use_prompt.go
client/cmd/use_test.go
Modified
client/internal/testing/runner.go
client/internal/testing/runner_test.go
client/cmd/root.go
Context
Sub-issue of #207 — Phase 3(A): Dedicated subcommands for calling individual
ql-mcpserver primitives, with shared Go library code reused by the integration test runner.Depends on: #217 (Phase 2 — Go binary and integration test runner)
Problem
After Phase 2, the
ql-mcp-clientGo binary can run integration tests and list registered primitives, but there is no way to call an individual prompt, resource, or tool from the CLI. Users who want to exercise a specificql-mcpserver primitive must either write ad-hoc scripts or use the integration test runner indirectly.Additionally, the integration test runner (
client/internal/testing/runner.go) contains its own inline logic for calling MCP primitives. This should be refactored so that the test runner and the newusesubcommands share the same Go library code for discovery, invocation, and response formatting.Requirements
New
usesubcommandsql-mcp-client use tool <name> [--arg key=value ...]— Call a specificql-mcpserver tool by name with key-value arguments, print the response to stdoutql-mcp-client use resource <uri>— Read a specificql-mcpserver resource by URI, print the content to stdoutql-mcp-client use prompt <name> [--arg key=value ...]— Get a specificql-mcpserver prompt by name with key-value arguments, print the resulting messages to stdoutShared primitive-calling Go library
client/internal/mcp/primitives.go— Shared Go package providing typed functions for calling individual MCP primitives:CallTool(client, name, args) → ToolResult— call a tool and return structured resultReadResource(client, uri) → ResourceContent— read a resource and return contentGetPrompt(client, name, args) → PromptMessages— get a prompt and return messagesListTools(client) → []ToolInfo— list available toolsListResources(client) → []ResourceInfo— list available resourcesListPrompts(client) → []PromptInfo— list available promptsclient/internal/mcp/primitives_test.go— Unit tests for the shared primitives libraryIntegration test runner refactoring
client/internal/testing/runner.go— Refactor to import and use the sharedclient/internal/mcpprimitives library for all MCP tool/prompt/resource calls, eliminating duplicated invocation logicOutput formatting
--format json(default) — raw JSON response from the MCP server--format text— human-readable text rendering of the response--format markdown— markdown rendering (useful for resource/prompt content)Example usage
Architecture
Key design constraint
The
client/internal/mcp/primitives.golibrary is the single source of truth for calling MCP primitives. Both theusesubcommands and the integration test runner must use this library — no separate implementations.Acceptance criteria
ql-mcp-client use tool <name> --arg k=vcalls the tool and prints the responseql-mcp-client use resource <uri>reads the resource and prints the contentql-mcp-client use prompt <name> --arg k=vgets the prompt and prints the messages--format json|text|markdownclient/internal/testing/runner.gousesclient/internal/mcp/primitives.gofor all MCP callsusesubcommands and the test runnergo test ./...passes all Go unit tests inclient/npm run build-and-testpasses end-to-endFiles changed
Added
Modified