Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
de07135
setup for chart mcp
Feb 4, 2026
aa0ae87
restarting project
Feb 4, 2026
c9924cc
temp folder for charts
Feb 4, 2026
f9e6292
server setup and temp chart folder created
Feb 4, 2026
e010852
mcp server config
qag4991 Feb 5, 2026
701394e
chart generator tool functioning with randomly generated data running…
Feb 5, 2026
d0464d1
changed png destination to temporary charts folder
Feb 5, 2026
c2d6541
test chart
Feb 5, 2026
5d1a57a
change image type
KeithN313 Feb 6, 2026
9ff0117
gitignore
KeithN313 Feb 6, 2026
2bd503b
merge
KeithN313 Feb 6, 2026
849576f
YAML configuration
KeithN313 Feb 6, 2026
b576f21
fixed yaml config
KeithN313 Feb 6, 2026
6a441c0
test file creation and updated prompt (passing test)
KeithN313 Feb 6, 2026
6ff82c5
updating prompt (gemini returning markdown fences)
KeithN313 Feb 9, 2026
4dd78fb
modifying prompt and adding reference images (current output neon col…
KeithN313 Feb 9, 2026
47844fb
updated prompt to be more creative
KeithN313 Feb 10, 2026
2bcfb12
Merge branch 'main' of https://github.com/RIT-AI-Club/FinRLExtention …
qag4991 Feb 11, 2026
1506813
perplexity server code is working, next steps are getting an api key …
qag4991 Feb 11, 2026
a239807
change in testing data and prompt formatting
KeithN313 Feb 11, 2026
9b767ab
addition to prompt for text preservation and donut charts
KeithN313 Feb 13, 2026
f98508f
refactoring to add config.py to initialize configuration
KeithN313 Feb 16, 2026
7b78fe2
refactoring files for readability and config
KeithN313 Feb 16, 2026
34545a4
updated notes for line chart server and added legend location functio…
Feb 19, 2026
7c298a3
Merge pull request
Feb 19, 2026
de65611
name change chart_mcp_server --> mcp_chart_generation & basic line ch…
Feb 19, 2026
3b2b096
sample charts from generation tests
Feb 19, 2026
1f3ebd7
removed legend functions for basic chart
Feb 19, 2026
16c1507
added transparent figure background to cleanup chart output
Feb 19, 2026
b662284
add html/css only test and attempt to change prompt to include text i…
KeithN313 Feb 19, 2026
10d20ff
updated label padding and generated new sample charts
Feb 19, 2026
fbdb8a0
perplexity server
qag4991 Feb 19, 2026
f02c015
Merge branch 'perplexity-mcp-server' of https://github.com/RIT-AI-Clu…
Feb 19, 2026
2b138f6
removed config to pull
Feb 19, 2026
f0f76f5
Revert "removed config to pull"
Feb 19, 2026
390b58c
fixed conflicts for merge
Feb 19, 2026
cc8adf8
made chart background transparent for generate_financial_line_chart()
Feb 19, 2026
e23d6fd
format cleanup for chart generator tools
Feb 19, 2026
9936d20
added default color for text
Feb 26, 2026
2ad5cf6
refactored basic and advanced line chart generators into one and touc…
Feb 26, 2026
1974cbb
changed date format to MM-DD-YYYY
Feb 26, 2026
b8a9c3b
modified _parse_dates to make it flexible | implemented better format…
Mar 3, 2026
4bfe070
added flexible tick locating and formatting for x-axis | generated mo…
Mar 3, 2026
af44006
removed manual print tests
Mar 4, 2026
328d5b4
removed extra x-axis padding | added f-string formatting for prices
Mar 4, 2026
362d5dd
decimal place formatting
Mar 4, 2026
54dfeae
changed time formatter to 12-hour time | improved tick spacing and pl…
Mar 5, 2026
98a9ca1
implemented dictionary theming for _build_base_chart
Mar 5, 2026
bd2403f
removed unecessary imports | cleaned up code
Mar 5, 2026
a1f16aa
more test charts
Mar 5, 2026
0bcdbb6
updated theme and docstring and removed text_color parameter
Mar 5, 2026
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
22 changes: 21 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,22 @@
=======
config/api_key.yml
config/config.yml
config.yml

# Ignore practice file
practice_formatting_server.py

# Ignore pycache files
pycache/__pycache__/
*.py[cod]

# Ignore virtual environment folders
venv/
env/
.virtualenv/

# Ignore IDE specific files
.vscode/

# Ignore test output files
*.html
*.pdf
26 changes: 10 additions & 16 deletions config/config.txt → config/mcpservers.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
# FinRLExtention Configuration

# Gemini API Configuration
gemini:
# API key for Google Gemini - replace with your actual key
api_key: "" # Set your API key here or use environment variable

# Model to use use this as default
model: "gemini-2.5-flash"

# Temperature for response generation (0.0 - 1.0)
temperature: 0.7

# Maximum tokens in the response
max_output_tokens: 8192

# MCP Server Configurations
# Add your MCP servers here

mcp_servers:
- name: "research"
command: "python"
args: ["src/backend/mcp_servers/mcp_research/server.py"]

# THIS IS THE FORMATTING SERVER (COMMENTED BECAUSE OF ERRORS THAT WILL NEED TO BE FIXED)
# - name: "formatting"
# command: "python"
# args: ["src/backend/mcp_servers/mcp_formatting/server.py"]

# Example server configuration:
# - name: "example-server"
# command: "python"
Expand Down
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ google-generativeai>=0.8.0

# MCP (Model Context Protocol) SDK
mcp>=1.0.0
fastmcp

# Configuration
pyyaml>=6.0

# OpenAI SDK (used for Perplexity API compatibility)
openai>=1.0.0

# Async support
anyio>=4.0.0
Binary file added src/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file added src/backend/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file not shown.
Binary file added src/backend/charts/sample_chart1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/backend/charts/sample_chart2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/backend/charts/sample_chart3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/backend/charts/sample_chart4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/backend/charts/sample_chart5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/backend/charts/sample_chart6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/backend/charts/sample_chart7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/backend/charts/sample_chart8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/backend/charts/sample_chart9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/backend/charts/temp_file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a temporary file.
Binary file added src/backend/charts/test_chart_output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 36 additions & 16 deletions src/backend/mcp_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import asyncio
import json
import logging
from contextlib import AsyncExitStack
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Optional
Expand Down Expand Up @@ -49,28 +50,35 @@ class MCPClient:
and uses Gemini to process user requests while handling tool calls.
"""

def __init__(self, config_path: Optional[str] = None):
def __init__(self, config_path: Optional[str] = None, mcp_servers_path: Optional[str] = None):
"""
Initialize the MCP Client.

Args:
config_path: Path to the config.yml file. If None, uses default location.
mcp_servers_path: Path to the mcpservers.yml file. If None, uses default location.
"""
self.config_path = Path(config_path) if config_path else self._get_default_config_path()
self.mcp_servers_path = Path(mcp_servers_path) if mcp_servers_path else self._get_default_mcp_servers_path()
self.config: dict[str, Any] = {}
self.gemini_config: Optional[GeminiConfig] = None
self.server_configs: list[MCPServerConfig] = []
self.sessions: dict[str, ClientSession] = {}
self.tools: dict[str, dict[str, Any]] = {}
self.tool_to_server: dict[str, str] = {}
self._model: Optional[genai.GenerativeModel] = None
self._exit_stack = AsyncExitStack()

def _get_default_config_path(self) -> Path:
"""Get the default config path relative to this file."""
return Path(__file__).parent.parent.parent / "config" / "config.yml"

def _get_default_mcp_servers_path(self) -> Path:
"""Get the default MCP servers config path relative to this file."""
return Path(__file__).parent.parent.parent / "config" / "mcpservers.yml"

def load_config(self) -> None:
"""Load configuration from the YAML config file."""
"""Load configuration from the YAML config files."""
if not self.config_path.exists():
raise FileNotFoundError(f"Config file not found: {self.config_path}")

Expand All @@ -90,7 +98,19 @@ def load_config(self) -> None:
max_output_tokens=gemini_cfg.get("max_output_tokens", 8192),
)

servers_cfg = self.config.get("mcp_servers", [])
self._load_mcp_servers_config()

def _load_mcp_servers_config(self) -> None:
"""Load MCP servers configuration from the mcpservers.yml file."""
if not self.mcp_servers_path.exists():
logger.warning(f"MCP servers config file not found: {self.mcp_servers_path}")
self.server_configs = []
return

with open(self.mcp_servers_path, "r") as f:
mcp_config = yaml.safe_load(f) or {}

servers_cfg = mcp_config.get("mcp_servers", [])
if servers_cfg is not None:
self.server_configs = [
MCPServerConfig(
Expand Down Expand Up @@ -135,11 +155,13 @@ async def connect_to_server(self, server_config: MCPServerConfig) -> ClientSessi
env=server_config.env if server_config.env else None,
)

stdio_transport = await stdio_client(server_params).__aenter__()
read_stream, write_stream = stdio_transport
read_stream, write_stream = await self._exit_stack.enter_async_context(
stdio_client(server_params)
)

session = ClientSession(read_stream, write_stream)
await session.__aenter__()
session = await self._exit_stack.enter_async_context(
ClientSession(read_stream, write_stream)
)
await session.initialize()

self.sessions[server_config.name] = session
Expand Down Expand Up @@ -378,29 +400,27 @@ def _convert_history_to_gemini(

async def close(self) -> None:
"""Close all server connections."""
for server_name, session in self.sessions.items():
try:
await session.__aexit__(None, None, None)
logger.info(f"Closed connection to {server_name}")
except Exception as e:
logger.error(f"Error closing connection to {server_name}: {e}")

await self._exit_stack.aclose()
self.sessions.clear()
self.tools.clear()
self.tool_to_server.clear()


async def create_mcp_client(config_path: Optional[str] = None) -> MCPClient:
async def create_mcp_client(
config_path: Optional[str] = None,
mcp_servers_path: Optional[str] = None,
) -> MCPClient:
"""
Create and initialize an MCP client.

Args:
config_path: Optional path to config file.
mcp_servers_path: Optional path to MCP servers config file.

Returns:
Initialized MCPClient instance.
"""
client = MCPClient(config_path)
client = MCPClient(config_path, mcp_servers_path)
client.load_config()
await client.connect_all_servers()
await client.discover_tools()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.14
Empty file.
Binary file not shown.
6 changes: 6 additions & 0 deletions src/backend/mcp_servers/mcp_chart_generation/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def main():
print("Hello from chart-mcp-server!")


if __name__ == "__main__":
main()
11 changes: 11 additions & 0 deletions src/backend/mcp_servers/mcp_chart_generation/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[project]
name = "chart-mcp-server"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.14"
dependencies = [
"fastmcp>=2.14.5",
"google-generativeai>=0.8.6",
"matplotlib>=3.10.8",
]
Loading