Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,49 @@ async def accept_completion_tool(completion_id: str) -> dict[str, Any]:
return await accept_completion(completion_id)


##################################################
## MCP Prompts
## - https://modelcontextprotocol.io/docs/concepts/prompts
##################################################


@mcp.prompt()
def generate_qiskit_code(task: str) -> str:
"""Generate Qiskit Python code for a quantum computing task."""
return (
f"Generate Qiskit code for: '{task}'. "
f"1) Call get_completion_tool with prompt='{task}' to generate the code, "
"2) Display the generated code from the response, "
"3) If the user confirms the code is useful, call accept_completion_tool "
"with the completion_id from the response."
)


@mcp.prompt()
def explain_qiskit_concept(concept: str) -> str:
"""Explain a Qiskit or quantum computing concept using the knowledge base."""
return (
f"Explain '{concept}' using the Qiskit Code Assistant knowledge base: "
f"Call get_rag_completion_tool with prompt='{concept}' and present the "
"explanation from the response. If the answer is helpful, call "
"accept_completion_tool with the completion_id."
)


@mcp.prompt()
def setup_model(model_id: str) -> str:
"""Set up a Qiskit Code Assistant model by reviewing its info and accepting the disclaimer."""
return (
f"Set up model '{model_id}' for use: "
f"1) Read the qca://model/{model_id} resource to get model details, "
f"2) Read the qca://disclaimer/{model_id} resource to get the disclaimer, "
"3) If a disclaimer is present, show it to the user and call "
f"accept_model_disclaimer_tool with model_id='{model_id}' and the "
"disclaimer_id from the response, "
"4) Confirm the model is ready for use."
)


if __name__ == "__main__":
import atexit

Expand Down
35 changes: 35 additions & 0 deletions qiskit-code-assistant-mcp-server/tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,39 @@ async def test_disclaimer_workflow(self, mock_env_vars, mock_http_responses):
assert accept_result["status"] == "success"


class TestServerRegistration:
"""Test that prompts and resource templates are registered."""

def test_prompts_registered(self):
"""Test that all expected prompts are registered."""
prompt_names = set(mcp._prompt_manager._prompts.keys())
expected_prompts = {
"generate_qiskit_code",
"explain_qiskit_concept",
"setup_model",
}
assert expected_prompts.issubset(prompt_names), (
f"Missing prompts: {expected_prompts - prompt_names}"
)

def test_prompt_count(self):
"""Test the expected number of prompts."""
assert len(mcp._prompt_manager._prompts) == 3

def test_resource_templates_registered(self):
"""Test that all expected resource templates are registered."""
template_uris = set(mcp._resource_manager._templates.keys())
expected_templates = {
"qca://model/{model_id}",
"qca://disclaimer/{model_id}",
}
assert expected_templates.issubset(template_uris), (
f"Missing resource templates: {expected_templates - template_uris}"
)

def test_resource_template_count(self):
"""Test the expected number of resource templates."""
assert len(mcp._resource_manager._templates) == 2


# Assisted by watsonx Code Assistant
Loading