Skip to content

ql-mcp-client Phase 4: use prompt, use resource, and use tool subcommands with shared primitive-calling library #222

@data-douser

Description

@data-douser

Context

Sub-issue of #207Phase 4: 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

  • ql-mcp-client use tool <name> [--arg key=value ...] — Call a specific ql-mcp server tool by name with key-value arguments, print the response to stdout
  • ql-mcp-client use resource <uri> — Read a specific ql-mcp server resource by URI, print the content to stdout
  • ql-mcp-client use prompt <name> [--arg key=value ...] — Get a specific ql-mcp server prompt by name with key-value arguments, print the resulting messages to stdout

Shared 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 result
    • ReadResource(client, uri) → ResourceContent — read a resource and return content
    • GetPrompt(client, name, args) → PromptMessages — get a prompt and return messages
    • ListTools(client) → []ToolInfo — list available tools
    • ListResources(client) → []ResourceInfo — list available resources
    • ListPrompts(client) → []PromptInfo — list available prompts
  • client/internal/mcp/primitives_test.go — Unit tests for the shared primitives library

Integration test runner refactoring

  • client/internal/testing/runner.go — Refactor to import and use the shared client/internal/mcp primitives library for all MCP tool/prompt/resource calls, eliminating duplicated invocation logic

Output 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

# 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

  1. ql-mcp-client use tool <name> --arg k=v calls the tool and prints the response
  2. ql-mcp-client use resource <uri> reads the resource and prints the content
  3. ql-mcp-client use prompt <name> --arg k=v gets the prompt and prints the messages
  4. All three subcommands support --format json|text|markdown
  5. The integration test runner in client/internal/testing/runner.go uses client/internal/mcp/primitives.go for all MCP calls
  6. No duplicated MCP invocation logic between the use subcommands and the test runner
  7. go test ./... passes all Go unit tests in client/
  8. All existing integration test fixtures still pass with the refactored test runner
  9. 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

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions