bridgemcp-logging
Structured invocation logging for BridgeMCP.
Every tool call, resource read, and prompt render is recorded with timing, exception details, and a structured log record. Zero configuration required.
Installation
pip install bridgemcp-logging
Requires bridgemcp-py >= 0.2.1 and Python 3.11+.
Quickstart
from bridgemcp import BridgeMCP
from bridgemcp_logging import LoggingPlugin
app = BridgeMCP(name="my-server")
app.register_plugin(LoggingPlugin())
@app.tool
def greet(name: str) -> str:
return f"Hello, {name}!"
app.run()
Console output for each call:
[2026-06-30 12:00:00Z] INFO tool:greet 2.1ms OK
Configuration
from bridgemcp_logging import LoggingPlugin, LoggingConfig, ConsoleHandler
plugin = LoggingPlugin(
config=LoggingConfig(
success_level="DEBUG", # level for successful calls (default: "INFO")
error_level="ERROR", # level for failed calls (default: "ERROR")
log_kwargs=True, # include call arguments in the record (default: False)
log_result=False, # include return values in the record (default: False)
),
handler=ConsoleHandler(stream=sys.stdout),
)
app.register_plugin(plugin)
log_kwargs and log_result are False by default because arguments and return values may contain secrets or large payloads. Enable them explicitly when needed.
Public API
LoggingPlugin
class LoggingPlugin(Plugin):
name = "bridgemcp-logging"
version: str # from installed package metadata
description: str
def __init__(
self,
config: LoggingConfig = LoggingConfig(),
handler: ConsoleHandler = ConsoleHandler(),
) -> None: ...
def setup(self, app: BridgeMCP) -> None: ...
async def on_startup(self, app: BridgeMCP) -> None: ...
async def on_shutdown(self, app: BridgeMCP) -> None: ...
LoggingConfig
class LoggingConfig(BaseModel, frozen=True):
success_level: str = "INFO"
error_level: str = "ERROR"
log_kwargs: bool = False
log_result: bool = False
InvocationRecord
@dataclass(frozen=True)
class InvocationRecord:
invocation_id: str
app_name: str
framework_version: str
plugin_version: str
primitive: str # "tool" | "resource" | "prompt"
name: str
kwargs: dict[str, Any] | None
result: Any
exception: Exception | None
exception_type: str | None
exception_chain: list[str]
succeeded: bool
duration_ms: float
started_at: datetime
finished_at: datetime
level: str
TextFormatter
class TextFormatter:
def format(self, record: InvocationRecord) -> str: ...
Produces one-line human-readable output:
[2026-06-30 12:00:00Z] INFO tool:greet 12.3ms OK
[2026-06-30 12:00:01Z] ERROR tool:send_email 3.2ms FAILED SMTPAuthenticationError: ...
ConsoleHandler
class ConsoleHandler:
def __init__(
self,
stream: TextIO = sys.stderr,
formatter: TextFormatter = TextFormatter(),
) -> None: ...
def emit(self, record: InvocationRecord) -> None: ...
def flush(self) -> None: ...
Exception handling
If a tool, resource, or prompt handler raises, the exception is captured in the InvocationRecord, the record is emitted, and the exception is re-raised. The logging plugin is transparent — it never swallows exceptions.
asyncio.CancelledError and KeyboardInterrupt are not captured (they are not Exception subclasses and should propagate without interference).
Middleware ordering
bridgemcp-logging should be the first plugin registered so its timing measurement covers the full middleware chain:
app.register_plugin(LoggingPlugin()) # outermost — measures total wall time
app.register_plugin(AuthPlugin())
app.register_plugin(RateLimitPlugin())
Versioning
bridgemcp-logging is versioned independently from bridgemcp-py. Compatible versions:
| bridgemcp-logging | bridgemcp-py |
|---|---|
| 0.1.x | >= 0.2.1 |
License
MIT — see LICENSE.
Official BridgeMCP Ecosystem
Framework
- BridgeMCP https://github.com/Arsie-codes/bridgemcp
Official Plugins
- bridgemcp-logging https://github.com/Arsie-codes/bridgemcp-logging
Official Servers
- bridgemcp-server-weather https://github.com/Arsie-codes/bridgemcp-server-weather
More official plugins and servers are currently under development.
Release files for bridgemcp-logging 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bridgemcp_logging-0.1.2.tar.gz | 14.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bridgemcp_logging-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 25.4 kB
Release files / bridgemcp_logging-0.1.2.tar.gz
| Download URL | bridgemcp_logging-0.1.2.tar.gz |
|---|---|
| Size | 14.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
017a0e38371d249ddd2499f73c336e2006643edd38794d43a0351bb2b15e9846
|
|
BLAKE2b-256 checksum How to use checksums |
7823201d52b5defb054d3f400fc2facf12e37a00236c2b3706d52a59aaf2271b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Release files / bridgemcp_logging-0.1.2-py3-none-any.whl
| Download URL | bridgemcp_logging-0.1.2-py3-none-any.whl |
|---|---|
| Size | 11.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
142e0fe9a756338d3d8fbf77de95d173d94d23df15914f3d8bd05c4d0ff8fc1d
|
|
BLAKE2b-256 checksum How to use checksums |
efcd551bfd73cff737751d82897bb420b165c867c63472556fb40c1d2b87b89f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|