---
schema: rendered-html/v1
title: "Local Provider - FastMCP"
source_url: https://gofastmcp.com/servers/providers/local
generated_at: 2026-06-11T19:38:25.037138+00:00
---




[FastMCP home page![light logo](images/gofastmcp__com__servers__providers__local__wordmark.avif)![dark logo](images/gofastmcp__com__servers__providers__local__wordmark-white.avif)](gofastmcp__com.md)


- [PrefectHQ/fastmcp](https://github.com/PrefectHQ/fastmcp "PrefectHQ/fastmcp")
- [PrefectHQ/fastmcp](https://github.com/PrefectHQ/fastmcp "PrefectHQ/fastmcp")



MCP Providers

Local Provider


⌘K







  - [Overview

    NEW](gofastmcp__com__servers__providers__overview.md)
  - [Local

    NEW](/servers/providers/local)
  - [Filesystem

    NEW](gofastmcp__com__servers__providers__filesystem.md)
  - [MCP Proxy](gofastmcp__com__servers__providers__proxy.md)
  - [Skills

    NEW](gofastmcp__com__servers__providers__skills.md)
  - [Composition](gofastmcp__com__servers__composition.md)
  - [Custom

    NEW](gofastmcp__com__servers__providers__custom.md)














- [How It Works](#how-it-works)
- [Component Registration](#component-registration)
  - [Using Decorators](#using-decorators)
  - [Using Direct Methods](#using-direct-methods)
  - [Removing Components](#removing-components)
- [Duplicate Handling](#duplicate-handling)
- [Component Visibility](#component-visibility)
- [Standalone LocalProvider](#standalone-localprovider)

MCP Providers

# Local Provider


The default provider for decorator-registered components


`LocalProvider` stores components that you define directly on your server. When you use `@mcp.tool`, `@mcp.resource`, or `@mcp.prompt`, you’re adding components to your server’s `LocalProvider`.

## [​](#how-it-works) How It Works

Every FastMCP server has a `LocalProvider` as its first provider. Components registered via decorators or direct methods are stored here:


mcp = FastMCP("MyServer")

# These are stored in the server's `LocalProvider`
def greet(name: str) -> str:
    """Greet someone by name."""
    return f"Hello, {name}!"

@mcp.resource("data://config")
def get_config() -> str:
    """Return configuration data."""
    return '{"version": "1.0"}'

@mcp.prompt
def analyze(topic: str) -> str:
    """Create an analysis prompt."""
    return f"Please analyze: {topic}"

The `LocalProvider` is always queried first when clients request components, ensuring that your directly-defined components take precedence over those from mounted or proxied servers.

## [​](#component-registration) Component Registration

### [​](#using-decorators) Using Decorators

The most common way to register components:

def my_tool(x: int) -> str:
    return str(x)

@mcp.resource("data://info")
def my_resource() -> str:
    return "info"

@mcp.prompt
def my_prompt(topic: str) -> str:
    return f"Discuss: {topic}"

### [​](#using-direct-methods) Using Direct Methods

You can also add pre-built component objects:

from fastmcp.tools import Tool

# Create a tool object
my_tool = Tool.from_function(some_function, name="custom_tool")

# Add it to the server
mcp.add_tool(my_tool)
mcp.add_resource(my_resource)
mcp.add_prompt(my_prompt)

### [​](#removing-components) Removing Components

Remove components by name or URI:

mcp.local_provider.remove_tool("my_tool")
mcp.local_provider.remove_resource("data://info")
mcp.local_provider.remove_prompt("my_prompt")

## [​](#duplicate-handling) Duplicate Handling

When you try to add a component that already exists, the behavior depends on the `on_duplicate` setting:

| Mode | Behavior |
| --- | --- |
| `"error"` (default) | Raise `ValueError` |
| `"warn"` | Log warning and replace |
| `"replace"` | Silently replace |
| `"ignore"` | Keep existing component |

Configure this when creating the server:

mcp = FastMCP("MyServer", on_duplicate="warn")

## [​](#component-visibility) Component Visibility

Components can be dynamically enabled or disabled at runtime. Disabled components don’t appear in listings and can’t be called.

@mcp.tool(tags={"admin"})
def delete_all() -> str:
    """Delete everything."""
    return "Deleted"

def get_status() -> str:
    """Get system status."""
    return "OK"

# Disable admin tools
mcp.disable(tags={"admin"})

# Or only enable specific tools
mcp.enable(keys={"tool:get_status"}, only=True)

See [Visibility](gofastmcp__com__servers__visibility.md) for the full documentation on keys, tags, allowlist mode, and provider-level control.

## [​](#standalone-localprovider) Standalone LocalProvider

You can create a LocalProvider independently and attach it to multiple servers:

from fastmcp.server.providers import LocalProvider

# Create a reusable provider
shared_tools = LocalProvider()

@shared_tools.tool
def greet(name: str) -> str:
    return f"Hello, {name}!"

@shared_tools.resource("data://version")
def get_version() -> str:
    return "1.0.0"

# Attach to multiple servers
server1 = FastMCP("Server1", providers=[shared_tools])
server2 = FastMCP("Server2", providers=[shared_tools])

This is useful for:

- Sharing components across servers
- Testing components in isolation
- Building reusable component libraries

Standalone providers also support visibility control with `enable()` and `disable()`. See [Visibility](gofastmcp__com__servers__visibility.md) for details.

[Providers

Previous](gofastmcp__com__servers__providers__overview.md)[Filesystem Provider

Next](gofastmcp__com__servers__providers__filesystem.md)

⌘I




