MCPcopy
hub / github.com/MinishLab/semble / create_server

Function create_server

src/semble/mcp.py:45–135  ·  view source on GitHub ↗

Build and return a configured FastMCP server backed by the given cache.

(cache: _IndexCache)

Source from the content-addressed store, hash-verified

43
44
45def create_server(cache: _IndexCache) -> FastMCP:
46 """Build and return a configured FastMCP server backed by the given cache."""
47 server = FastMCP(
48 "semble",
49 instructions=(
50 "Instant code search for any local or remote git repository. "
51 "Call `search` once with a focused query, it returns the file path and exact line. "
52 "Navigate directly to that file at the given line; do not grep for the same content. "
53 "Use `find_related` to discover similar code elsewhere in the same repo. "
54 "When working in a local project, pass the project root as `repo`. "
55 "For remote repos, pass an explicit https:// URL. Never guess or infer URLs."
56 ),
57 )
58
59 @server.tool()
60 async def search(
61 query: Annotated[str, Field(description="Natural language or code query.")],
62 repo: Annotated[str, Field(description=_REPO_DESCRIPTION)],
63 top_k: Annotated[int, Field(description="Number of results to return.", ge=1)] = 5,
64 max_snippet_lines: Annotated[
65 int | None,
66 Field(
67 description=(
68 "Lines of source to include per result. "
69 "Default (10): function/class signature + first body lines, enough to confirm the location. "
70 "0: file path and line range only. None: full chunk (~10-20 lines). "
71 "If the snippet does not contain enough context to confirm you have the right location, "
72 "call again with max_snippet_lines=None."
73 ),
74 ge=0,
75 ),
76 ] = 10,
77 ) -> str:
78 """Search once with a focused query describing what the code does or its name.
79
80 Write queries using function/class names or behavior descriptions, not error messages.
81 Returns file paths and line numbers — navigate directly there, do not repeat the search.
82 Pass a git URL or local path as `repo`; indexes are cached for the session.
83 """
84 try:
85 index = await _get_index(repo, cache)
86 except ValueError as exc:
87 return str(exc)
88 results = index.search(query, top_k=top_k, max_snippet_lines=max_snippet_lines)
89 if not results:
90 return json.dumps({"error": "No results found."})
91 return json.dumps(format_results(query, results, max_snippet_lines))
92
93 @server.tool()
94 async def find_related(
95 file_path: Annotated[
96 str,
97 Field(description="Path to the file as stored in the index (use file_path from a search result)."),
98 ],
99 line: Annotated[int, Field(description="Line number (1-indexed).")],
100 repo: Annotated[str, Field(description=_REPO_DESCRIPTION)],
101 top_k: Annotated[int, Field(description="Number of similar chunks to return.", ge=1)] = 5,
102 max_snippet_lines: Annotated[

Callers 4

_call_toolFunction · 0.90
test_tool_index_failureFunction · 0.90
serveFunction · 0.85

Calls

no outgoing calls

Tested by 3

_call_toolFunction · 0.72
test_tool_index_failureFunction · 0.72