Implement new MCP server usage.

Rework Agents description
Add new logging info
This commit is contained in:
2026-08-22 10:24:28 +09:00
parent afb10aa52e
commit 63a95dec00
2 changed files with 41 additions and 26 deletions
+38 -23
View File
@@ -41,13 +41,20 @@ def create_crew(config):
# 1. DEFINE CUSTOM TOOLS & OUTPUT SCHEMAS
# ==========================================
class CompetitorDetail(BaseModel):
company_name: str = PydanticField(..., description="The name of the competitor company.")
pricing_range: str = PydanticField(..., description="Pricing tiers or estimated cost ranges.")
core_features: List[str] = PydanticField(..., description="Key modules, tools, or features offered.")
target_audience: str = PydanticField(..., description="The primary customer profile or ideal user persona.")
class ResearchEvidence(BaseModel):
source_url: str = PydanticField(..., description="The source URL of the evidence.")
claim: str = PydanticField(..., description="The factual finding or data point.")
context: str = PydanticField(..., description="The context or time frame of this data point.")
class ResearchOutputSchema(BaseModel):
competitors: List[Dict[str, Any]] = PydanticField(..., description="List of competitors with products pricing range, features, and target audience.")
# CHANGED: Replaced List[Dict[str, Any]] with List[CompetitorDetail]
competitors: List[CompetitorDetail] = PydanticField(..., description="List of competitors with products pricing range, features, and target audience.")
market_trends: List[str] = PydanticField(..., description="Market Analysis & Growth Trends")
evidence_citations: List[ResearchEvidence] = PydanticField(..., description="Valid source citations for facts collected.")
@@ -154,7 +161,7 @@ def create_crew(config):
return f"Error executing search: {str(e)}"
@tool("FastMCP Batch Web Content extraction Tool")
def fastmcp_batch_web_content_extraction_tool(urls: list[str]) -> str:
def fastmcp_batch_web_content_extraction_tool(urls: list[str], query: str) -> str:
"""
Connects directly to the FastMCP HTTP server to scrape and extract text from
a list of multiple URLs simultaneously in parallel.
@@ -164,8 +171,8 @@ def create_crew(config):
transport = StreamableHttpTransport("http://localhost:8000/mcp/")
async with Client(transport) as client:
# call_tool abstracts away deep JSON-RPC structures perfectly
result = await client.call_tool("batch_web_content_extraction", {"urls": urls})
# call_tool abstracts away deep JSON-RPC structures
result = await client.call_tool("batch_web_content_extraction", {"urls": urls, "query": query})
return result
try:
@@ -191,10 +198,10 @@ def create_crew(config):
formatted_output.append(f"CONTENT:\n{item['content']}\n")
formatted_output.append("=" * 40 + "\n")
logger.info(f"""FastMCP Batch Web Content extraction tool used.\nURLs:\n{"\n".join(urls)}\nResult:\n{"\n".join(formatted_output)}""")
logger.info(f"""FastMCP Batch Web Content extraction tool used.\nURLs:\n{"\n".join(urls)}\nQuery: {query}\nResult:\n{"\n".join(formatted_output)}""")
return "\n".join(formatted_output)
except json.JSONDecodeError:
logger.info(f"""FastMCP Batch Web Content extraction tool used. Error in JSON formatting so raw data returned:\nURLs:\n{"\n".join(urls)}\nResult:\n{raw_content}""")
logger.info(f"""FastMCP Batch Web Content extraction tool used. Error in JSON formatting so raw data returned:\nURLs:\n{"\n".join(urls)}\nQuery: {query}\nResult:\n{raw_content}""")
return raw_content
except Exception as e:
@@ -209,7 +216,8 @@ def create_crew(config):
llm = LLM(
model=config.model,
api_key=os.getenv("OPENAI_API_KEY"),
temperature=config.temperature,
temperature=config.temperature if config.model != "gpt-5-mini" else 1,
#reasoning_effort="low",
max_completion_tokens=config.max_tokens,
)
else:
@@ -250,7 +258,7 @@ def create_crew(config):
verbose=verbose,
tools=[web_search_tool, fastmcp_batch_web_content_extraction_tool],
use_system_prompt=False,
llm=llm
llm=llm,
)
# 3. analyst
@@ -262,6 +270,7 @@ def create_crew(config):
#goal='Synthesize raw market data into structured frameworks like SWOT, 4P, 7P, and target user personas.',
#backstory='You are a data-driven Strategic Analyst. You look past surface-level facts to find underlying market gaps, evaluate competitive positioning, and model risks.',
verbose=verbose,
use_system_prompt=False,
llm=llm
)
@@ -274,6 +283,7 @@ def create_crew(config):
#goal='Formulate the actionable Go-To-Market blueprint, positioning, pricing strategies, and launch timelines.',
#backstory='You are a veteran GTM Growth Strategist. You specialize in crafting commercial launch playbooks, positioning products uniquely against rivals, and designing user-acquisition loops.',
verbose=verbose,
use_system_prompt=False,
llm=llm
)
# ---------------------------------------------------------
@@ -292,17 +302,20 @@ def create_crew(config):
# "Do not fabricate any data and do not make assumptions. Only include verifiable facts using working URLs."
# "If you cannot find a specific metric, leave it blank and do not fabricate data."
description=("""
1. Using your Web Search Tool, search websites for the compagnies related the target market: '{query}'. When sending the search query, do not add any information about the year. It should be the most recent data.
2. Review the result snippets and keep URLs that match the target market. Make sure URLs are not borken or do not redirect to "Not Found" website
3. Collect those URLs into a list and feed them into the 'FastMCP Batch Web Content Extraction Tool' in a single call.
4. Review the returned parallel scrape data and extract following information:
a. List of compagnies with products pricing range, keys features, and target audience. Do not list more than one time a specific compagny.
b. Market Analysis & Growth Trends
c. Evidence citations which include URL, the factual finding or data point and the context or time frame of this data point.
5. Every single metric or claim MUST have a URL source tracked inside the JSON structure.
Research for competitor compagnies in the target market: {query}
Use your Web Search tool to find relevant and recent company, product, industry, and market sources. Do not add a year to the search query. Remove broken, duplicate, or irrelevant URLs.
Create a focused MCP query that describes the information needed, including products, pricing, key features, target customers, market trends, growth, and competitive information.
Send the selected URLs and the focused query to the FastMCP Batch Web Content Extraction Tool in a single call.
Analyze the returned content and produce:
Companies/products: company, products, price range, key features, and target audience. Do not duplicate companies.
Market analysis: market characteristics, growth, trends, drivers, and competitive developments.
Evidence: every factual claim or metric must have a source URL, factual finding, and context/timeframe.
Prefer primary and authoritative sources. Do not invent information. If information is unavailable, state that it was not found.
Critical: Every factual claim, metric, price, feature, market statistic, or growth figure must be traceable to a source URL.
Return valid JSON:
"""
),
expected_output="A structured JSON file matching the schema and strict citation tracking.",
expected_output="A structured JSON payload containing validated competitor profiles, trend metrics, and verifiable source citations.",
output_json=ResearchOutputSchema,
agent=researcher_agent
)
@@ -310,9 +323,10 @@ def create_crew(config):
# Task 2: Analyst Agent creates comparative structures
analysis_task = Task(
description=(
"Review the structured JSON output provided by the Research Agent. "
"Construct a detailed markdown competitive landscape table and a pricing matrix. Include source URL in the table."
"Perform a comprehensive SWOT, 4P, and 7P analysis based strictly on the evidence compiled."
"1. Extract and read the text/JSON-formatted market research data passed to you from the Research Agent in the context below.\n"
"2. Using that data, construct a detailed markdown competitive landscape table and a pricing matrix. Ensure every row includes its respective source URL.\n"
"3. Perform a comprehensive SWOT, 4P, and 7P analysis based strictly on the facts and evidence compiled by the Research Agent.\n"
"4. Do not speculate or invent market details not present in the research context data."
),
expected_output="A deep-dive analytical report featuring clean markdown tables, a SWOT quadrant, and an exhaustive 4P/7P matrix analysis.",
context=[research_task],
@@ -325,7 +339,7 @@ def create_crew(config):
"Take the analytical matrices and SWOT outputs to build a comprehensive GTM document. "
"Define 2 distinct Ideal Customer Profiles (ICPs). Outline the core value proposition. "
"Create a messaging framework (Hook, Problem, Solution) per ICP. "
"Identify high-ROI acquisition channels and detail a 30-60-90 day milestone launch plan."
"Identify high-ROI acquisition channels and detail a 30-60-90 day milestone launch plan." \
),
expected_output="An actionable, comprehensive market entry strategy blueprint divided into logical execution phases.",
context=[analysis_task],
@@ -337,7 +351,8 @@ def create_crew(config):
description=(
"""Synthesize the outputs from the Research, Analyst, and Strategy agents into a seamless, high-caliber Master GTM Report.
Include all research data tables, citations, SWOT/7P strategic matrices, and execution timelines.
Include a title and small summary that cleary identifies the target market and highlights the core value proposition. Include the input query '{query}' for reference at the end of the summary.
Include a title
Inlude small summary that cleary identifies the target market including the input query '{query}' for reference.
Include a table of contents.
Include a conclusion and Evidence Citations section at the end.
Ensure the document is formatted for executive-level presentation.
+3 -3
View File
@@ -36,8 +36,8 @@ if "chat_history" not in st.session_state:
#llm_model = "gpt-4o" #Output~ 10 US$ / 1M tokens
#llm_model = "gpt-5.5" #Output~ 30 US$ / 1M tokens
MODEL_REGISTRY={
"OpenAI":["gpt-4o-mini","gpt-5.4-nano","gpt-5-mini","gpt-4.1","gpt-4o","gpt-3.5-turbo"],
"Ollama":["gemma4:e4b","llama3.1","gpt-oss:20b","qwen2.5-coder:14b","mistral-small3.2"],
"OpenAI":["gpt-4o-mini","gpt-5-mini","gpt-5.4-nano","gpt-4.1","gpt-4o","gpt-3.5-turbo"],
"Ollama":["llama3.1","gemma4:e4b","gpt-oss:20b","qwen2.5-coder:14b","mistral-small3.2"],
}
#7- Creating Sidebar
@@ -67,7 +67,7 @@ with st.sidebar:
config.max_tokens=st.slider(
"Max Tokens",
min_value=100,
max_value=30000,
max_value=10000,
value=config.max_tokens,
step=100
)