1+ import argparse
12import asyncio
23import logging
34import os
45import sys
6+ from dataclasses import dataclass
57from pathlib import Path
68from typing import Optional
79
3133from vectorcode .subcommands .query import get_query_result_files
3234
3335logger = logging .getLogger (name = __name__ )
34- mcp = FastMCP ("VectorCode" , instructions = "\n " .join (prompt_strings ))
36+
37+
38+ @dataclass
39+ class MCPConfig :
40+ n_results : int = 10
41+ ls_on_start : bool = False
42+
43+
44+ mcp_config = MCPConfig ()
45+
46+
47+ def get_arg_parser ():
48+ parser = argparse .ArgumentParser (prog = "vectorcode-mcp-server" )
49+ parser .add_argument (
50+ "--number" ,
51+ "-n" ,
52+ type = int ,
53+ default = 10 ,
54+ help = "Default number of files to retrieve." ,
55+ )
56+ parser .add_argument (
57+ "--ls-on-start" ,
58+ action = "store_true" ,
59+ default = False ,
60+ help = "Whether to include the output of `vectorcode ls` in the tool description." ,
61+ )
62+ return parser
3563
3664
3765default_config : Optional [Config ] = None
@@ -114,6 +142,7 @@ async def query_tool(
114142
115143async def mcp_server ():
116144 global default_config , default_client , default_collection
145+
117146 local_config_dir = await find_project_config_dir ("." )
118147
119148 if local_config_dir is not None :
@@ -128,9 +157,23 @@ async def mcp_server():
128157 try :
129158 default_collection = await get_collection (default_client , default_config )
130159 logger .info ("Collection initialised for %s." , project_root )
131- except InvalidCollectionException :
160+ except InvalidCollectionException : # pragma: nocover
132161 default_collection = None
133162
163+ default_instructions = "\n " .join (prompt_strings )
164+ if default_client is None :
165+ if mcp_config .ls_on_start : # pragma: nocover
166+ logger .warning (
167+ "Failed to initialise a chromadb client. Ignoring --ls-on-start flag."
168+ )
169+ else :
170+ if mcp_config .ls_on_start :
171+ logger .info ("Adding available collections to the server instructions." )
172+ default_instructions += "\n You have access to the following collections:\n "
173+ for name in await list_collections ():
174+ default_instructions += f"<collection>{ name } </collection>"
175+
176+ mcp = FastMCP ("VectorCode" , instructions = default_instructions )
134177 mcp .add_tool (
135178 fn = list_collections ,
136179 name = "ls" ,
@@ -140,24 +183,36 @@ async def mcp_server():
140183 mcp .add_tool (
141184 fn = query_tool ,
142185 name = "query" ,
143- description = """
186+ description = f """
144187Use VectorCode to perform vector similarity search on repositories and return a list of relevant file paths and contents.
145188Make sure `project_root` is one of the values from the `ls` tool.
189+ Unless the user requested otherwise, start your retrievals by { mcp_config .n_results } files.
146190The result contains the relative paths for the files and their corresponding contents.
147191""" ,
148192 )
149193
150194 return mcp
151195
152196
197+ def parse_cli_args (args : Optional [list [str ]] = None ) -> MCPConfig :
198+ parser = get_arg_parser ()
199+ parsed_args = parser .parse_args (args or sys .argv )
200+ return MCPConfig (n_results = parsed_args .number , ls_on_start = parsed_args .ls_on_start )
201+
202+
153203async def run_server (): # pragma: nocover
154204 mcp = await mcp_server ()
155205 await mcp .run_stdio_async ()
156206 return 0
157207
158208
159209def main (): # pragma: nocover
210+ global mcp_config
160211 config_logging ("vectorcode-mcp-server" , stdio = False )
212+ mcp_config = parse_cli_args ()
213+ assert mcp_config .n_results > 0 and mcp_config .n_results % 1 == 0 , (
214+ "--number must be used with a positive integer!"
215+ )
161216 return asyncio .run (run_server ())
162217
163218
0 commit comments