Skip to main content

spakky-mcp

spakky-mcp is the Spakky Agent connector for external MCP servers.

It does one thing: connect MCP servers selected at run time and make their tools callable by the agent. It does not build MCP servers, and it does not expose an agent's own tools as an MCP server.

When to use it

Use this plugin when an agent service needs to attach MCP servers supplied by the developer, the service, or the end user:

  • a configured company MCP server,
  • a tenant-specific remote MCP endpoint,
  • a user-connected GitHub/Linear/search MCP server,
  • a per-run inline MCP server declaration.

The MCP server itself can be implemented with FastMCP, the official MCP SDK, or any compatible server implementation.

Install

uv add spakky-mcp
# or through the agent bundle
uv add "spakky[agent]"

Loading the plugin registers McpClient as IAgentRunnerFactory. Inbound adapters such as AG-UI and A2A can keep using the runner factory; MCP servers join the run through RunAgentInput.metadata.

Configure servers

Configured servers use the SPAKKY_MCP__ settings prefix.

export SPAKKY_MCP__SERVERS='[
  {"name": "weather", "transport": "stdio", "command": "weather-mcp-server"}
]'
Setting Meaning Default
SPAKKY_MCP__SERVERS JSON array of external MCP server declarations []
SPAKKY_MCP__CONNECT_TIMEOUT_SECONDS MCP connection timeout in seconds 30.0

Server fields:

Field Meaning
name Unique server name for one run. It cannot contain __.
transport stdio or streamable_http
command, args, env stdio server process command, arguments, and environment
url streamable HTTP MCP endpoint
auth.headers Static HTTP headers
auth.bearer_token_env Environment variable containing a bearer token
auth.oauth_client_credentials OAuth2 client-credentials token request config
call_timeout_seconds Per-tool call timeout. Default 60.0

Runtime selection

At run time, pass configured server names or inline declarations through RunAgentInput.metadata["mcp"]["servers"].

from spakky.agent import IAgentRunnerFactory, RunAgentInput


async def run_with_user_mcp(factory: IAgentRunnerFactory, agent: object) -> None:
    run_input = RunAgentInput(
        state_id="run-1",
        instruction="answer with external tools",
        metadata={"mcp": {"servers": ["weather"]}},
    )
    async with factory.open_runner(agent, run_input=run_input) as runner:
        async for item in runner.run(run_input):
            ...

Inline server declarations support user self-service connections:

RunAgentInput(
    state_id="run-2",
    instruction="inspect issue status",
    metadata={
        "mcp": {
            "servers": [
                {
                    "name": "tenant-linear",
                    "transport": "streamable_http",
                    "url": "https://tenant.example.com/mcp",
                    "auth": {"bearer_token": access_token},
                }
            ]
        }
    },
)

Production services usually implement IMcpRuntimeServerResolver so a request carries stable connection IDs, while the server loads URLs and credentials from a DB or vault. Register that resolver as a Pod and bind it over the default resolver:

from spakky.core.application.application import SpakkyApplication
from spakky.core.application.plugin import Plugin
from spakky.plugins.mcp import IMcpRuntimeServerResolver


PLUGIN_NAME = Plugin(name="my-mcp-connections")


def initialize(app: SpakkyApplication) -> None:
    app.add(UserMcpResolver)
    app.container.bind_to_type(IMcpRuntimeServerResolver, UserMcpResolver)

Browser users should generally be allowed to add streamable_http endpoints, not arbitrary stdio commands.

AG-UI maps forwardedProps.mcp into the same metadata shape. A2A maps the data part mcp object into the same shape.

Lazy tool search

MCP servers can expose many tools. spakky-mcp does not push every external tool schema into the initial model request. The model sees only two MCP meta-tools:

Tool Purpose
mcp_search_tools Search tools available from the MCP servers attached to this run.
mcp_call_tool Call one tool returned by mcp_search_tools.

External tool names are returned by search as <server_name>__<tool_name>. For example, weather server tool forecast becomes weather__forecast.

This keeps large MCP toolsets from polluting the model context while still letting the model discover and invoke the tools it needs. When mcp_call_tool requires human approval, the approval request names the selected external MCP tool and includes the selected arguments in metadata.

Development checks

Run package checks from this package directory:

uv run ruff format .
uv run ruff check .
uv run --project ../.. pyrefly check --disable-project-excludes-heuristics --min-severity warn --no-progress-bar --output-format min-text
uv run pytest

License

MIT License

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spakky_mcp-8.0.0.tar.gz (14.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spakky_mcp-8.0.0-py3-none-any.whl (18.7 kB view details)

Uploaded Python 3

File details

Details for the file spakky_mcp-8.0.0.tar.gz.

File metadata

  • Download URL: spakky_mcp-8.0.0.tar.gz
  • Upload date:
  • Size: 14.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for spakky_mcp-8.0.0.tar.gz
Algorithm Hash digest
SHA256 9a380f3818de8c53ba1e63e233c2f2a61a883ff64e4d0d5933a2457f40f683d3
MD5 4309f86a91fd66cdc71b1e0f0d9f23a0
BLAKE2b-256 91711c522af1da23cf52623143497a7002c9ca2022b50e78d4467071908d7b11

See more details on using hashes here.

Provenance

The following attestation bundles were made for spakky_mcp-8.0.0.tar.gz:

Publisher: release.yml on E5presso/spakky-framework

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file spakky_mcp-8.0.0-py3-none-any.whl.

File metadata

  • Download URL: spakky_mcp-8.0.0-py3-none-any.whl
  • Upload date:
  • Size: 18.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for spakky_mcp-8.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 44a43b51ab2a6690db39f15bc0333b441ba0a6ee37fd548a36102a1b4cb32e87
MD5 e3da74a1cd7722416e555946ecb6f334
BLAKE2b-256 cf2e592ad45212c5445c3149a110aff8695a04e21bb226af500d5de17031ffcf

See more details on using hashes here.

Provenance

The following attestation bundles were made for spakky_mcp-8.0.0-py3-none-any.whl:

Publisher: release.yml on E5presso/spakky-framework

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

8.1.0

2 files

This release

8.0.0 This release

2 files

7.2.0

2 files

7.1.1

2 files

7.1.0

2 files

7.0.0

2 files

6.13.0

2 files

6.12.0

2 files

6.11.0

2 files

6.10.1

2 files

6.10.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page