MCPcopy
hub / github.com/github/github-mcp-server / Build

Method Build

pkg/inventory/builder.go:212–276  ·  view source on GitHub ↗

Build creates the final Inventory with all configuration applied. This processes toolset filtering, tool name resolution, and sets up the inventory for use. The returned Inventory is ready for use with AvailableTools(), RegisterAll(), etc. Build returns an error if any tools specified via WithTools

()

Source from the content-addressed store, hash-verified

210// (i.e., they don't exist in the tool set and are not deprecated aliases).
211// This ensures invalid tool configurations fail fast at build time.
212func (b *Builder) Build() (*Inventory, error) {
213 tools := b.tools
214
215 // Install the feature-flag filter at the head of the pipeline so that
216 // flag-gated tools are excluded before any user-supplied WithFilter sees
217 // them. Doing this in Build() (rather than inside WithFeatureChecker)
218 // keeps the install idempotent — repeated WithFeatureChecker calls
219 // replace the checker without stacking duplicate filters.
220 filters := b.filters
221 if b.featureChecker != nil {
222 filters = append([]ToolFilter{createFeatureFlagFilter(b.featureChecker)}, filters...)
223 }
224
225 r := &Inventory{
226 tools: tools,
227 resourceTemplates: b.resourceTemplates,
228 prompts: b.prompts,
229 deprecatedAliases: b.deprecatedAliases,
230 readOnly: b.readOnly,
231 featureChecker: b.featureChecker,
232 filters: filters,
233 }
234
235 // Process toolsets and pre-compute metadata in a single pass
236 r.enabledToolsets, r.unrecognizedToolsets, r.toolsetIDs, r.toolsetIDSet, r.defaultToolsetIDs, r.toolsetDescriptions = b.processToolsets()
237
238 // Build set of valid tool names for validation
239 validToolNames := make(map[string]bool, len(tools))
240 for i := range tools {
241 validToolNames[tools[i].Tool.Name] = true
242 }
243
244 // Process additional tools (clean, resolve aliases, and track unrecognized)
245 if len(b.additionalTools) > 0 {
246 cleanedTools := cleanTools(b.additionalTools)
247
248 r.additionalTools = make(map[string]bool, len(cleanedTools))
249 var unrecognizedTools []string
250 for _, name := range cleanedTools {
251 // Always include the original name - this handles the case where
252 // the tool exists but is controlled by a feature flag that's OFF.
253 r.additionalTools[name] = true
254 // Also include the canonical name if this is a deprecated alias.
255 // This handles the case where the feature flag is ON and only
256 // the new consolidated tool is available.
257 if canonical, isAlias := b.deprecatedAliases[name]; isAlias {
258 r.additionalTools[canonical] = true
259 } else if !validToolNames[name] {
260 // Not a valid tool and not a deprecated alias - track as unrecognized
261 unrecognizedTools = append(unrecognizedTools, name)
262 }
263 }
264
265 // Error out if there are unrecognized tools
266 if len(unrecognizedTools) > 0 {
267 return nil, fmt.Errorf("%w: %s", ErrUnknownTools, strings.Join(unrecognizedTools, ", "))
268 }
269 }

Calls 4

processToolsetsMethod · 0.95
createFeatureFlagFilterFunction · 0.85
cleanToolsFunction · 0.85
generateInstructionsFunction · 0.85