Tool

Build Model Context Protocol servers declaratively in Golang

Golang library for declaratively building MCP servers with dependency-injected tools, resources, and prompts.

Works with golangfx

28
Spark score
out of 100
Updated 10 months ago
Source checked Sep 10, 2026
Version 0.0.14

Add to Favorites

Why it matters

Developers hire this library to rapidly build MCP-compliant context servers in Go using a declarative, dependency-injection approach that cleanly separates tool definitions, resource providers, and prompt logic into reusable, testable components.

Outcomes

What it gets done

01

Define MCP tools, resources, and prompts with colocated schemas and execution logic

02

Wire dependencies using Uber's fx framework for shared clients and connections

03

Support stdio, SSE, and HTTP transports for MCP protocol communication

04

Validate tool inputs and test servers functionally with the foxytest package

Source

Get it from source

A library you build with. Add it to your project from the source. Spark does not host a copy of it.

Open source
  1. 1

    Clone the repository and open an example server. (README)

    git clone https://github.com/strowk/foxy-contexts cd foxy-contexts/examples/list_current_dir_files_tool
  2. 2

    Run it under the MCP inspector, then open http://localhost:6274 and call list-current-dir-files. (README)

    npx @modelcontextprotocol/inspector go run main.go

Requires: Go, Node.js with npx (for the inspector)

Reports

Agent outcome reports

No reports yet

Overview

Foxy Contexts

Foxy Contexts is a Golang library for declaratively building MCP servers: tools, resources, and prompts are defined and registered with an fx-based app.Builder, colocating each one's logic with dependency-injected shared clients. Use it to build an MCP server in Go with a declarative, DI-friendly structure. Resource templates, subscriptions, pagination, and several notification types are still planned, not yet implemented.

What it does

Foxy Contexts is a Golang library for building the server side of Model Context Protocol servers declaratively. Instead of hand-wiring dispatch logic, you define tools, resources, and prompts and register them with an app.Builder (built on Uber's fx dependency-injection framework), which colocates each tool's definition with its call/read/get logic while letting shared dependencies - clients, database connections, and the like - be injected rather than duplicated.

When to use - and when NOT to

Use it when you're building an MCP server in Go and want a declarative, DI-friendly structure rather than assembling the protocol by hand. It already covers the core surface - tools, static and dynamic (Resource Provider-backed) resources, prompts with completion, and Stdio, SSE, and beta Streamable HTTP transports - with a functional-testing package (foxytest) included. It's explicitly a work in progress: resource templates and their completion, resource subscriptions, pagination, list_changed notifications, sampling, roots, and MCP-native logging are all still planned, not implemented, so don't reach for it if your server needs any of those today.

Capabilities

  • Declarative tool, resource, and prompt definitions registered on an app.Builder, with dependency injection via fx for shared clients/connections.
  • Transports: Stdio, SSE, and Streamable HTTP (beta).
  • The toolinput package for defining a tool's input schema and validating incoming arguments.
  • Static resources and dynamic resources backed by Resource Providers.
  • Prompts, including prompt completion.
  • A functional-testing package, foxytest, for testing MCP servers built with the library.

How to install

Try the bundled example:

git clone https://github.com/strowk/foxy-contexts
cd foxy-contexts/examples/list_current_dir_files_tool
npx @modelcontextprotocol/inspector go run main.go

then open http://localhost:6274 in a browser and run the list-current-dir-files tool through the MCP Inspector. A minimal server defines a tool with fxctx.NewTool (an mcp.Tool struct for name/description/input schema, plus a callback that returns an mcp.CallToolResult), then wires it up with app.NewBuilder().WithTool(...).WithName(...).WithVersion(...).WithTransport(stdio.NewTransport()).Run().

Who it's for

Go developers who want to build an MCP server using a declarative, dependency-injected structure instead of wiring protocol handling by hand, and who can tolerate a library that's still adding features like resource templates, subscriptions, and pagination. The project's own checklist tracks this progress publicly, alongside base lifecycle/ping support and a roadmap for progress notifications, so it's straightforward to see exactly what's implemented before committing to it for a given server. The library is documented with a dedicated docs site and a set of runnable examples beyond the bundled directory-listing tool, covering fuller real-world setups.

Source README

main logo
Foxy Contexts

Build MCP Servers Declaratively in Golang

Go Reference Go Reference

Features 🦊 Tool Example 🦊 Docs 🦊 Sources

Foxy contexts is a Golang library for building context servers supporting Model Context Protocol.

This library only supports server side of the protocol. Using it you can build context servers using declarative approach, by defining tools, resources and prompts and then registering them with your app.Builder, which is using uber's fx App under the hood and you can inject into its container as well.

With this approach you can easily colocate call/read/get logic and definitions of your tools/resources/prompts in a way that every tool/resource/prompt is placed in a separate place, while Dependency Injection allows you to reuse shared parts like clients, database connections, etc.

Features

Here is list of features that are implemented and planned:

  • Base (lifecycle/ping)
    • Progress (planned)
  • Transports
    • Stdio Transport
    • SSE Transport
    • Streamable HTTP Transport (beta)
  • Tools
    • Package toolinput helps define tools input schema and validate arriving input
  • Resources
    • Resources - static
    • Resources - dynamic via Resource Providers
    • Resources - dynamic via Resource Templates (planned)
    • Resource Templates completion (planned)
    • Resource subscriptions
  • Prompts
  • Prompts Completion
  • Functional Testing package foxytest
  • Simple building of your MCP server with the power of Dependency Injection
  • Logging via MCP (planned)
  • Sampling (planned)
  • Roots (planned)
  • Pagination (planned)
  • Notifications list_changed (planned)
  • Testing - functional tests with foxytest package

Check docs and examples to know more.

Tool Example

For example try following

git clone https://github.com/strowk/foxy-contexts
cd foxy-contexts/examples/list_current_dir_files_tool
npx @modelcontextprotocol/inspector go run main.go

, then once inspector is started in browser open http://localhost:6274 and try to use list-current-dir-files.

Here's the code of that example from examples/list_current_dir_files_tool/main.go (in real world application you would probably want to split it into multiple files):

package main

import (
	"fmt"
	"os"

	"github.com/strowk/foxy-contexts/pkg/app"
	"github.com/strowk/foxy-contexts/pkg/fxctx"
	"github.com/strowk/foxy-contexts/pkg/mcp"
	"github.com/strowk/foxy-contexts/pkg/stdio"
	"go.uber.org/fx"
	"go.uber.org/fx/fxevent"
	"go.uber.org/zap"
)

// This example defines list-current-dir-files tool for MCP server, that prints files in the current directory
// , run it with:
// npx @modelcontextprotocol/inspector go run main.go
// , then in browser open http://localhost:6274
// , then click Connect
// , then click List Tools
// , then click list-current-dir-files

// NewListCurrentDirFilesTool defines a tool that lists files in the current directory
func NewListCurrentDirFilesTool() fxctx.Tool {
	return fxctx.NewTool(
		// This information about the tool would be used when it is listed:
		&mcp.Tool{
			Name:        "list-current-dir-files",
			Description: Ptr("Lists files in the current directory"),
			InputSchema: mcp.ToolInputSchema{
				Type:       "object",
				Properties: map[string]map[string]interface{}{},
				Required:   []string{},
			},
		},

		// This is the callback that would be executed when the tool is called:
		func(_ context.Context, args map[string]interface{}) *mcp.CallToolResult {
			files, err := os.ReadDir(".")
			if err != nil {
				return &mcp.CallToolResult{
					IsError: Ptr(true),
					Meta:    map[string]interface{}{},
					Content: []interface{}{
						mcp.TextContent{
							Type: "text",
							Text: fmt.Sprintf("failed to read dir: %v", err),
						},
					},
				}
			}
			var contents []interface{} = make([]interface{}, len(files))
			for i, f := range files {
				contents[i] = mcp.TextContent{
					Type: "text",
					Text: f.Name(),
				}
			}

			return &mcp.CallToolResult{
				Meta:    map[string]interface{}{},
				Content: contents,
				IsError: Ptr(false),
			}
		},
	)
}

func main() {
	app.
		NewBuilder().
		// adding the tool to the app
		WithTool(NewListCurrentDirFilesTool).
		// setting up server
		WithName("list-current-dir-files").
		WithVersion("0.0.1").
		WithTransport(stdio.NewTransport()).
		// Configuring fx logging to only show errors
		WithFxOptions(fx.Provide(func() *zap.Logger {
				cfg := zap.NewDevelopmentConfig()
				cfg.Level.SetLevel(zap.ErrorLevel)
				logger, _ := cfg.Build()
				return logger
			}),
			fx.Option(fx.WithLogger(
				func(logger *zap.Logger) fxevent.Logger {
					return &fxevent.ZapLogger{Logger: logger}
				},
			)),
		).
		Run()
}

func Ptr[T any](v T) *T {
	return &v
}

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.