Skip to content

Frameworks

MCP

AlterMCP, AlterAuthProvider, AlterContext — FastMCP integration.

The alter_sdk.mcp module integrates with FastMCP so any MCP server can ship as a full OAuth 2.0 Authorization Server backed by Alter’s hosted IDP flow.

Requires the mcp extra:

Terminal window
pip install 'alter-sdk[mcp]'
from fastmcp import FastMCP
from alter_sdk import App
from alter_sdk.mcp import AlterMCP, AlterAuthProvider, AlterContext
mcp = FastMCP("my-server")
alter_app = App(api_key="alter_rk_…")
alter = AlterMCP(alter_app)
@mcp.tool()
@alter.tool(provider="google")
async def list_emails(ctx: AlterContext, query: str) -> list[dict]:
resp = await ctx.request(
"GET",
"https://gmail.googleapis.com/gmail/v1/users/me/messages",
query_params={"q": query},
)
return resp.json()
if __name__ == "__main__":
mcp.run()
AlterMCP(vault: App | Agent)

Wrapper around an SDK client that exposes the @alter.tool() decorator.

def tool(
provider: str,
*,
scope: list[str] | None = None,
constraints: dict[str, Any] | None = None,
agent: Agent | None = None,
) -> Callable[[F], F]
ParameterTypeDefaultDescription
providerstrOAuth provider id (e.g. "google", "github", "slack").
scopelist[str] | NoneNoneReserved code-level scope declaration. Stored on AlterContext.scope for introspection. Not yet forwarded.
constraintsdict | NoneNoneReserved. Stored on AlterContext.constraints.
agentAgent | NoneNoneOptional Agent whose identity should drive this tool’s requests. Same-Task nesting records the outer agent as parent_agent.

The decorator:

  1. Creates an AlterContext pre-configured with the provider and any code-level scope / constraints.
  2. Sets an ambient audit ContextVar so vault.request() calls inside the tool body pick up the tool name automatically.
  3. Hides the AlterContext parameter from FastMCP’s generated tool schema.
  4. Catches GrantNotFoundError and returns an MCP error with a fresh Connect URL.
  5. Catches ScopeReauthRequiredError and returns an MCP error with a re-auth hint.
from fastmcp import FastMCP
mcp = FastMCP("my-server")
@mcp.tool()
@alter.tool(provider="github")
async def list_repos(ctx: AlterContext) -> list[dict]:
resp = await ctx.request("GET", "https://api.github.com/user/repos")
return resp.json()

Per-tool-call request context injected by @alter.tool(). Not constructed directly.

AlterContext(
vault: App | Agent,
*,
provider: str,
scope: list[str] | None = None,
constraints: dict[str, Any] | None = None,
context: dict[str, str] | None = None,
)
PropertyTypeDescription
providerstrThe OAuth provider id declared on the decorator.
scopetuple[str, ...] | NoneReserved scope declaration.
constraintsMapping[str, Any] | NoneReserved constraints declaration (immutable view).

Forwards to the underlying vault.request() with provider= and context= pre-filled. Tool implementations only specify method + URL.

resp = await ctx.request(
"GET",
"https://gmail.googleapis.com/gmail/v1/users/me/messages",
query_params={"q": "from:alice"},
)

A FastMCP OAuthProvider that turns any MCP server into a full OAuth 2.0 Authorization Server backed by Alter’s IDP flow. Spec-compliant MCP clients can discover, register, authorize, and obtain tokens without mcp-remote or any other shim.

AlterAuthProvider(
vault: App | Agent,
*,
base_url: str,
providers: dict[str, list[str]] | None = None,
)
ParameterTypeDefaultDescription
vaultApp | AgentSDK client to back the OAuth flow.
base_urlstrPublic URL where the MCP server is mounted (e.g. "http://localhost:8000/mcp"). Required for OAuth metadata discovery.
providersdict[str, list[str]] | NoneNoneMap of provider_id → required scopes for the Connect flow.
from fastmcp import FastMCP
from alter_sdk import App
from alter_sdk.mcp import AlterAuthProvider
vault = App(api_key="alter_rk_…")
auth = AlterAuthProvider(
vault,
base_url="http://localhost:8000/mcp",
providers={"google": ["gmail.readonly"]},
)
mcp = FastMCP("Gmail", auth=auth)

Pair with AlterFastAPI.auth_provider() when the same vault should serve both FastAPI and MCP traffic.

Re-exported by alter_sdk.mcp so subclass authors can annotate load_access_token / verify_token overrides on AlterAuthProvider subclasses without reaching into FastMCP’s namespace directly.

from alter_sdk.mcp import AccessToken