aiohttp-tiny-mcp 0.5.6__tar.gz → 0.5.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/PKG-INFO +1 -1
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/pyproject.toml +1 -1
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/pyproject.toml.orig +1 -1
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/adapter.py +16 -1
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/models.py +11 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/v2024_11_05.py +2 -2
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/v2025_03_26.py +2 -2
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/v2025_11_25.py +1 -1
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/v2026_07_28.py +1 -1
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/exchange.py +2 -2
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/http.py +12 -9
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/specs.py +11 -1
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/sse.py +4 -2
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/stdio.py +7 -5
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/transport/sse.py +3 -2
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/LICENSE +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/README.md +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/__init__.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/auth/__init__.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/auth/jwt.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/client/__init__.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/client/base.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/client/http.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/client/stdio.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/console/__init__.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/console/console.css +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/console/console.js +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/console/index.html +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/console/oauth-callback.html +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/extensions/__init__.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/extensions/skills.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/oauth/__init__.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/oauth/github.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/oauth/provider.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/oauth/server.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/oauth/tokens.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/__init__.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/core.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/schema.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/selection.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/v2025_06_18.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/py.typed +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/__init__.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/dispatcher.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/registry.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/request_state.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/subscriptions.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/tasks.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/storage/__init__.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/storage/hub.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/storage/namespaces.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/storage/postgres.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/storage/redis.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/storage/sessions.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/storage/sqlite.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/testing.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/transport/__init__.py +0 -0
- {aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/transport/metadata.py +0 -0
|
@@ -320,8 +320,23 @@ class Adapter(ABC):
|
|
|
320
320
|
def describe_server(self, registry: RegistryProtocol, call: Call) -> BaseModel:
|
|
321
321
|
"""Negotiate the requested legacy revision from `call.params.protocol_version`."""
|
|
322
322
|
|
|
323
|
+
def describe_tool(self, spec: ToolSpec) -> ToolDef | None:
|
|
324
|
+
"""Return how this revision shows `spec`, or None where it hides it.
|
|
325
|
+
|
|
326
|
+
The projection is cached on the spec. A tool does not change after
|
|
327
|
+
registration, so each revision simplifies its schemas once instead of
|
|
328
|
+
once per `tools/list` and once per `tools/call`.
|
|
329
|
+
"""
|
|
330
|
+
cache = spec.described
|
|
331
|
+
try:
|
|
332
|
+
return cache[self.version]
|
|
333
|
+
except KeyError:
|
|
334
|
+
definition = cache[self.version] = self.build_tool(spec)
|
|
335
|
+
return definition
|
|
336
|
+
|
|
323
337
|
@abstractmethod
|
|
324
|
-
def
|
|
338
|
+
def build_tool(self, spec: ToolSpec) -> ToolDef | None:
|
|
339
|
+
"""Project `spec` onto this revision. `describe_tool` caches the result."""
|
|
325
340
|
|
|
326
341
|
def describe_resource(self, spec: ResourceSpec) -> ResourceDef | ResourceTemplateDef | None:
|
|
327
342
|
"""Project extension resources onto the URI understood by this revision."""
|
|
@@ -10,6 +10,17 @@ from typing import Annotated, Any, Literal
|
|
|
10
10
|
|
|
11
11
|
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
|
|
12
12
|
from pydantic.alias_generators import to_camel
|
|
13
|
+
from pydantic_core import to_json
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def serialized(payload: Any) -> bytes:
|
|
17
|
+
"""Encode one wire payload as UTF-8 JSON.
|
|
18
|
+
|
|
19
|
+
`to_json` is the serializer pydantic already carries. It is about three
|
|
20
|
+
times faster than `json.dumps` and writes the same bytes for the JSON-mode
|
|
21
|
+
values `Model.wire` returns. Non-ASCII characters stay as they are.
|
|
22
|
+
"""
|
|
23
|
+
return to_json(payload)
|
|
13
24
|
|
|
14
25
|
|
|
15
26
|
class Model(BaseModel):
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/v2024_11_05.py
RENAMED
|
@@ -16,8 +16,8 @@ class Adapter2024_11_05(Adapter2025_03_26): # noqa: N801 -- revision date, grep
|
|
|
16
16
|
allows_batch: ClassVar[bool] = False
|
|
17
17
|
progress_message: ClassVar[bool] = False
|
|
18
18
|
|
|
19
|
-
def
|
|
20
|
-
definition = super().
|
|
19
|
+
def build_tool(self, spec: ToolSpec) -> ToolDef | None:
|
|
20
|
+
definition = super().build_tool(spec)
|
|
21
21
|
if definition is None:
|
|
22
22
|
return None
|
|
23
23
|
return definition.model_copy(update={"annotations": None})
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/v2025_03_26.py
RENAMED
|
@@ -86,8 +86,8 @@ class Adapter2025_03_26(Adapter2025_06_18): # noqa: N801 -- revision date, grep
|
|
|
86
86
|
"""Only handlers receiving Exchange need the extra answer/state arguments."""
|
|
87
87
|
return any(kind.__name__ == "Exchange" for _, kind in spec.bound.plan)
|
|
88
88
|
|
|
89
|
-
def
|
|
90
|
-
definition = super().
|
|
89
|
+
def build_tool(self, spec: ToolSpec) -> ToolDef | None:
|
|
90
|
+
definition = super().build_tool(spec)
|
|
91
91
|
if definition is None:
|
|
92
92
|
return None
|
|
93
93
|
definition = definition.model_copy(update={"output_schema": None, "title": None})
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/v2025_11_25.py
RENAMED
|
@@ -135,7 +135,7 @@ class Adapter2025_11_25(Adapter): # noqa: N801 -- revision date, greppable agai
|
|
|
135
135
|
instructions=registry.instructions,
|
|
136
136
|
)
|
|
137
137
|
|
|
138
|
-
def
|
|
138
|
+
def build_tool(self, spec: ToolSpec) -> ToolDef | None:
|
|
139
139
|
if spec.min_revision is not None and spec.min_revision > self.version:
|
|
140
140
|
return None
|
|
141
141
|
schema = simplify_legacy_schema(spec.input_schema)
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/v2026_07_28.py
RENAMED
|
@@ -341,7 +341,7 @@ class Adapter2026_07_28(Adapter): # noqa: N801 -- revision date, greppable agai
|
|
|
341
341
|
caps["extensions"] = extensions
|
|
342
342
|
return caps
|
|
343
343
|
|
|
344
|
-
def
|
|
344
|
+
def build_tool(self, spec: ToolSpec) -> ToolDef | None:
|
|
345
345
|
if spec.min_revision is not None and spec.min_revision > self.version:
|
|
346
346
|
return None
|
|
347
347
|
return spec.definition(spec.input_schema, spec.output_schema)
|
|
@@ -4,7 +4,6 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import inspect
|
|
7
|
-
import json
|
|
8
7
|
import logging
|
|
9
8
|
from collections.abc import Awaitable, Callable, Mapping
|
|
10
9
|
from contextlib import AsyncExitStack, asynccontextmanager
|
|
@@ -25,6 +24,7 @@ from aiohttp_tiny_mcp.protocol.core import (
|
|
|
25
24
|
answer_of,
|
|
26
25
|
logs_at,
|
|
27
26
|
)
|
|
27
|
+
from aiohttp_tiny_mcp.protocol.models import serialized
|
|
28
28
|
from aiohttp_tiny_mcp.storage.hub import ASK, Hub, topic
|
|
29
29
|
from aiohttp_tiny_mcp.storage.sessions import Session, SessionAccess
|
|
30
30
|
from aiohttp_tiny_mcp.storage.sessions import new_session_id as new_id
|
|
@@ -232,7 +232,7 @@ class Exchange:
|
|
|
232
232
|
await self.send(payload)
|
|
233
233
|
return
|
|
234
234
|
assert self.sse is not None
|
|
235
|
-
text =
|
|
235
|
+
text = serialized(payload).decode()
|
|
236
236
|
log.debug("-> [%s] %s", self.adapter.version, text)
|
|
237
237
|
await self.sse.send(text)
|
|
238
238
|
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
-
import json
|
|
7
6
|
import logging
|
|
8
7
|
import re
|
|
9
8
|
from collections.abc import Mapping
|
|
@@ -26,6 +25,7 @@ from aiohttp_tiny_mcp.protocol.core import (
|
|
|
26
25
|
Rejected,
|
|
27
26
|
Value,
|
|
28
27
|
)
|
|
28
|
+
from aiohttp_tiny_mcp.protocol.models import serialized
|
|
29
29
|
from aiohttp_tiny_mcp.protocol.selection import AdapterSet
|
|
30
30
|
from aiohttp_tiny_mcp.storage.hub import NOTIFICATIONS, Subscription, topic
|
|
31
31
|
from aiohttp_tiny_mcp.storage.namespaces import current, namespace, scoped
|
|
@@ -325,7 +325,8 @@ class Endpoint:
|
|
|
325
325
|
return self.render_failure(self.adapters.fallback(), e.failure)
|
|
326
326
|
held = self.open_values(request, session)
|
|
327
327
|
|
|
328
|
-
log.
|
|
328
|
+
if log.isEnabledFor(logging.DEBUG):
|
|
329
|
+
log.debug("<- [%s] %s", adapter.version, raw.decode("utf-8", "replace"))
|
|
329
330
|
|
|
330
331
|
try:
|
|
331
332
|
items = adapter.decode(pre, self.registry)
|
|
@@ -390,13 +391,13 @@ class Endpoint:
|
|
|
390
391
|
return web.Response(
|
|
391
392
|
status=200,
|
|
392
393
|
content_type="application/json",
|
|
393
|
-
|
|
394
|
+
body=serialized([p for _, p in replies]),
|
|
394
395
|
)
|
|
395
396
|
status, payload = replies[0]
|
|
396
397
|
response = web.Response(
|
|
397
398
|
status=status,
|
|
398
399
|
content_type="application/json",
|
|
399
|
-
|
|
400
|
+
body=serialized(payload),
|
|
400
401
|
)
|
|
401
402
|
if minted is not None:
|
|
402
403
|
response.headers[SESSION_HEADER] = minted
|
|
@@ -466,7 +467,7 @@ class Endpoint:
|
|
|
466
467
|
)
|
|
467
468
|
for event in found:
|
|
468
469
|
if relays(event.message, accepted):
|
|
469
|
-
text =
|
|
470
|
+
text = serialized(event.message).decode()
|
|
470
471
|
log.debug("-> [%s] %s %s", adapter.version, event.id, text)
|
|
471
472
|
await response.send(text, id=event.id)
|
|
472
473
|
|
|
@@ -561,15 +562,17 @@ class Endpoint:
|
|
|
561
562
|
) -> tuple[int, Mapping[str, Any]]:
|
|
562
563
|
status = adapter.http_status(outcome) if isinstance(outcome, Failure) else 200
|
|
563
564
|
payload = adapter.encode(call, self.registry, outcome)
|
|
564
|
-
log.
|
|
565
|
+
if log.isEnabledFor(logging.DEBUG):
|
|
566
|
+
log.debug("-> [%s] %s %s", adapter.version, status, serialized(payload).decode())
|
|
565
567
|
return status, payload
|
|
566
568
|
|
|
567
569
|
def render_failure(self, adapter: Adapter, failure: Failure) -> web.Response:
|
|
568
570
|
payload = adapter.encode_failure(None, failure)
|
|
569
|
-
|
|
570
|
-
log.
|
|
571
|
+
body = serialized(payload)
|
|
572
|
+
if log.isEnabledFor(logging.DEBUG):
|
|
573
|
+
log.debug("-> [%s] %s %s", adapter.version, adapter.http_status(failure), body.decode())
|
|
571
574
|
return web.Response(
|
|
572
|
-
status=adapter.http_status(failure), content_type="application/json",
|
|
575
|
+
status=adapter.http_status(failure), content_type="application/json", body=body
|
|
573
576
|
)
|
|
574
577
|
|
|
575
578
|
async def stream(self, request: web.Request, ex: Exchange) -> web.StreamResponse:
|
|
@@ -10,7 +10,7 @@ from collections.abc import Awaitable, Callable, Iterable, Mapping
|
|
|
10
10
|
from contextlib import AbstractAsyncContextManager
|
|
11
11
|
from typing import Any, ClassVar, Literal, Protocol, get_type_hints
|
|
12
12
|
|
|
13
|
-
from pydantic import BaseModel, ConfigDict, Field
|
|
13
|
+
from pydantic import BaseModel, ConfigDict, Field, PrivateAttr
|
|
14
14
|
|
|
15
15
|
from aiohttp_tiny_mcp.protocol.models import (
|
|
16
16
|
BlobResourceContents,
|
|
@@ -101,6 +101,16 @@ class ToolSpec(Model):
|
|
|
101
101
|
min_revision: str | None = None
|
|
102
102
|
streaming: bool = False
|
|
103
103
|
|
|
104
|
+
#: One projection of this tool per revision, keyed by adapter version.
|
|
105
|
+
#: A spec never changes after registration, so each revision simplifies
|
|
106
|
+
#: the schema once instead of once per request. `None` means the revision
|
|
107
|
+
#: hides the tool. `Adapter.describe_tool` owns this cache.
|
|
108
|
+
_described: dict[str, ToolDef | None] = PrivateAttr(default_factory=dict)
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def described(self) -> dict[str, ToolDef | None]:
|
|
112
|
+
return self._described
|
|
113
|
+
|
|
104
114
|
@classmethod
|
|
105
115
|
def build(
|
|
106
116
|
cls,
|
|
@@ -23,6 +23,7 @@ from aiohttp_tiny_mcp.protocol.core import (
|
|
|
23
23
|
Rejected,
|
|
24
24
|
Value,
|
|
25
25
|
)
|
|
26
|
+
from aiohttp_tiny_mcp.protocol.models import serialized
|
|
26
27
|
from aiohttp_tiny_mcp.protocol.selection import AdapterSet
|
|
27
28
|
from aiohttp_tiny_mcp.storage.hub import NOTIFICATIONS, Subscription, topic
|
|
28
29
|
from aiohttp_tiny_mcp.storage.namespaces import scoped
|
|
@@ -184,7 +185,7 @@ class SseEndpoint:
|
|
|
184
185
|
)
|
|
185
186
|
for event in found:
|
|
186
187
|
if relays(event.message, accepted):
|
|
187
|
-
text =
|
|
188
|
+
text = serialized(event.message).decode()
|
|
188
189
|
await self.write(response, "message", text)
|
|
189
190
|
|
|
190
191
|
async def write(self, response: SSEResponse, event: str, data: str) -> None:
|
|
@@ -211,7 +212,8 @@ class SseEndpoint:
|
|
|
211
212
|
)
|
|
212
213
|
|
|
213
214
|
raw = await request.read()
|
|
214
|
-
log.
|
|
215
|
+
if log.isEnabledFor(logging.DEBUG):
|
|
216
|
+
log.debug("<- [%s] %s", VERSION, raw.decode("utf-8", "replace"))
|
|
215
217
|
where = topic(STREAM, session_id)
|
|
216
218
|
|
|
217
219
|
pre = Preamble.of(raw, request.headers)
|
|
@@ -7,7 +7,6 @@ In-flight tasks support subscriptions and cancellation. HTTP header checks belon
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
9
|
import asyncio
|
|
10
|
-
import json
|
|
11
10
|
import logging
|
|
12
11
|
import sys
|
|
13
12
|
from collections.abc import Callable, Mapping
|
|
@@ -23,6 +22,7 @@ from aiohttp_tiny_mcp.protocol.core import (
|
|
|
23
22
|
Preamble,
|
|
24
23
|
Rejected,
|
|
25
24
|
)
|
|
25
|
+
from aiohttp_tiny_mcp.protocol.models import serialized
|
|
26
26
|
from aiohttp_tiny_mcp.protocol.selection import AdapterSet
|
|
27
27
|
|
|
28
28
|
from .dispatcher import Dispatcher
|
|
@@ -60,7 +60,8 @@ async def serve_stdio(
|
|
|
60
60
|
level: list[str | None] = [None]
|
|
61
61
|
|
|
62
62
|
def send(version: str, payload: Mapping[str, Any]) -> None:
|
|
63
|
-
log.
|
|
63
|
+
if log.isEnabledFor(logging.DEBUG):
|
|
64
|
+
log.debug("-> [%s] %s", version, serialized(payload).decode())
|
|
64
65
|
write(payload)
|
|
65
66
|
|
|
66
67
|
def keep_log_level(value: str) -> None:
|
|
@@ -98,7 +99,8 @@ async def serve_stdio(
|
|
|
98
99
|
if not raw:
|
|
99
100
|
continue
|
|
100
101
|
|
|
101
|
-
log.
|
|
102
|
+
if log.isEnabledFor(logging.DEBUG):
|
|
103
|
+
log.debug("<- %s", raw.decode("utf-8", "replace"))
|
|
102
104
|
pre = Preamble.of(raw, {})
|
|
103
105
|
if is_reply(pre.body):
|
|
104
106
|
await relay_reply(registry.hub, pre.body)
|
|
@@ -172,8 +174,8 @@ async def stdin_reader() -> asyncio.StreamReader:
|
|
|
172
174
|
|
|
173
175
|
|
|
174
176
|
def write_stdout(payload: Mapping[str, Any]) -> None:
|
|
175
|
-
sys.stdout.write(
|
|
176
|
-
sys.stdout.flush()
|
|
177
|
+
sys.stdout.buffer.write(serialized(payload) + b"\n")
|
|
178
|
+
sys.stdout.buffer.flush()
|
|
177
179
|
|
|
178
180
|
|
|
179
181
|
async def run_stdio(
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
-
import json
|
|
7
6
|
from collections.abc import AsyncIterator, Mapping
|
|
8
7
|
from dataclasses import dataclass, replace
|
|
9
8
|
from typing import Any, ClassVar
|
|
@@ -14,6 +13,8 @@ from aiohttp import web
|
|
|
14
13
|
from aiohttp.compression_utils import ZLibCompressor
|
|
15
14
|
from multidict import CIMultiDict, CIMultiDictProxy
|
|
16
15
|
|
|
16
|
+
from aiohttp_tiny_mcp.protocol.models import serialized
|
|
17
|
+
|
|
17
18
|
BOM = b"\xef\xbb\xbf"
|
|
18
19
|
|
|
19
20
|
|
|
@@ -188,7 +189,7 @@ class SSEResponse(web.StreamResponse):
|
|
|
188
189
|
async def send_json(
|
|
189
190
|
self, value: Any, *, event: str | None = None, id: str | None = None
|
|
190
191
|
) -> None:
|
|
191
|
-
await self.send(
|
|
192
|
+
await self.send(serialized(value).decode(), event=event, id=id)
|
|
192
193
|
|
|
193
194
|
async def comment(self, text: str = "") -> None:
|
|
194
195
|
await self.push(SSEEvent(comment=text))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/console/oauth-callback.html
RENAMED
|
File without changes
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/extensions/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/selection.py
RENAMED
|
File without changes
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/protocol/v2025_06_18.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/request_state.py
RENAMED
|
File without changes
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/server/subscriptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/storage/namespaces.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/transport/__init__.py
RENAMED
|
File without changes
|
{aiohttp_tiny_mcp-0.5.6 → aiohttp_tiny_mcp-0.5.7}/src/aiohttp_tiny_mcp/transport/metadata.py
RENAMED
|
File without changes
|