aiohttp-tiny-mcp 0.1.0__py3-none-any.whl

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.
Files changed (41) hide show
  1. aiohttp_tiny_mcp/__init__.py +76 -0
  2. aiohttp_tiny_mcp/adapter.py +321 -0
  3. aiohttp_tiny_mcp/auth.py +129 -0
  4. aiohttp_tiny_mcp/client.py +111 -0
  5. aiohttp_tiny_mcp/client_base.py +295 -0
  6. aiohttp_tiny_mcp/console/__init__.py +98 -0
  7. aiohttp_tiny_mcp/console/console.css +525 -0
  8. aiohttp_tiny_mcp/console/console.js +1273 -0
  9. aiohttp_tiny_mcp/console/index.html +100 -0
  10. aiohttp_tiny_mcp/core.py +327 -0
  11. aiohttp_tiny_mcp/dispatcher.py +309 -0
  12. aiohttp_tiny_mcp/endpoint.py +531 -0
  13. aiohttp_tiny_mcp/exchange.py +279 -0
  14. aiohttp_tiny_mcp/http_sse.py +267 -0
  15. aiohttp_tiny_mcp/hub.py +109 -0
  16. aiohttp_tiny_mcp/models.py +346 -0
  17. aiohttp_tiny_mcp/namespaces.py +36 -0
  18. aiohttp_tiny_mcp/postgres.py +454 -0
  19. aiohttp_tiny_mcp/protocol/__init__.py +0 -0
  20. aiohttp_tiny_mcp/protocol/selection.py +92 -0
  21. aiohttp_tiny_mcp/protocol/v2024_11_05.py +30 -0
  22. aiohttp_tiny_mcp/protocol/v2025_03_26.py +165 -0
  23. aiohttp_tiny_mcp/protocol/v2025_06_18.py +11 -0
  24. aiohttp_tiny_mcp/protocol/v2025_11_25.py +164 -0
  25. aiohttp_tiny_mcp/protocol/v2026_07_28.py +363 -0
  26. aiohttp_tiny_mcp/py.typed +0 -0
  27. aiohttp_tiny_mcp/redis.py +195 -0
  28. aiohttp_tiny_mcp/registry.py +162 -0
  29. aiohttp_tiny_mcp/request_state.py +107 -0
  30. aiohttp_tiny_mcp/schema.py +131 -0
  31. aiohttp_tiny_mcp/sessions.py +347 -0
  32. aiohttp_tiny_mcp/specs.py +268 -0
  33. aiohttp_tiny_mcp/sqlite.py +236 -0
  34. aiohttp_tiny_mcp/sse.py +260 -0
  35. aiohttp_tiny_mcp/stdio.py +187 -0
  36. aiohttp_tiny_mcp/stdio_client.py +91 -0
  37. aiohttp_tiny_mcp/subscriptions.py +124 -0
  38. aiohttp_tiny_mcp/testing.py +200 -0
  39. aiohttp_tiny_mcp-0.1.0.dist-info/METADATA +12 -0
  40. aiohttp_tiny_mcp-0.1.0.dist-info/RECORD +41 -0
  41. aiohttp_tiny_mcp-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,525 @@
1
+
2
+ :root {
3
+ color-scheme: light dark;
4
+
5
+ --ink: #17181c;
6
+ --ink-soft: #5b6070;
7
+ --ink-faint: #8b90a0;
8
+ --page: #f6f7f9;
9
+ --card: #ffffff;
10
+ --line: #dfe2e9;
11
+ --accent: #2f6df6;
12
+ --accent-ink: #ffffff;
13
+ --good: #1a7f4b;
14
+ --bad: #c0342b;
15
+ --warn: #a06000;
16
+ --sent: #2f6df6;
17
+ --received: #6b4bd6;
18
+
19
+ --radius: 8px;
20
+ --gap: 12px;
21
+ --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
22
+ --sans: system-ui, -apple-system, "Segoe UI", sans-serif;
23
+ }
24
+
25
+ @media (prefers-color-scheme: dark) {
26
+ :root {
27
+ --ink: #e6e8ee;
28
+ --ink-soft: #a3a9bb;
29
+ --ink-faint: #757c92;
30
+ --page: #14151a;
31
+ --card: #1c1e25;
32
+ --line: #2c2f3a;
33
+ --accent: #5b8cff;
34
+ --accent-ink: #0d1016;
35
+ --good: #4cc38a;
36
+ --bad: #ff6b6b;
37
+ --warn: #e0a33a;
38
+ --sent: #5b8cff;
39
+ --received: #a78bfa;
40
+ }
41
+ }
42
+
43
+ * { box-sizing: border-box; }
44
+
45
+ body {
46
+ margin: 0;
47
+ font: 14px/1.5 var(--sans);
48
+ color: var(--ink);
49
+ background: var(--page);
50
+ height: 100vh;
51
+ display: flex;
52
+ flex-direction: column;
53
+ }
54
+
55
+
56
+ .bar {
57
+ display: flex;
58
+ align-items: center;
59
+ gap: var(--gap);
60
+ padding: 10px 16px;
61
+ background: var(--card);
62
+ border-bottom: 1px solid var(--line);
63
+ flex-wrap: wrap;
64
+ }
65
+
66
+ .bar h1 {
67
+ font-size: 15px;
68
+ font-weight: 600;
69
+ margin: 0 8px 0 0;
70
+ letter-spacing: -0.01em;
71
+ }
72
+
73
+ .field { display: flex; align-items: center; gap: 6px; }
74
+ .field > span { color: var(--ink-soft); font-size: 12px; }
75
+
76
+ input[type="text"], input[type="number"], select, textarea {
77
+ font: inherit;
78
+ color: inherit;
79
+ background: var(--page);
80
+ border: 1px solid var(--line);
81
+ border-radius: 6px;
82
+ padding: 5px 8px;
83
+ }
84
+
85
+ input[type="text"]:focus, select:focus, textarea:focus, input[type="number"]:focus {
86
+ outline: 2px solid var(--accent);
87
+ outline-offset: -1px;
88
+ }
89
+
90
+ .endpoint, select.revision {
91
+ font-family: var(--mono);
92
+ font-size: 12px;
93
+ background: var(--page);
94
+ border: 1px solid var(--line);
95
+ border-radius: 6px;
96
+ padding: 4px 8px;
97
+ }
98
+
99
+ select.revision { font-weight: 500; cursor: pointer; }
100
+
101
+ .greeting { color: var(--ink-soft); margin: 0 0 14px; }
102
+ .greeting:empty { display: none; }
103
+ textarea { font-family: var(--mono); font-size: 12px; width: 100%; min-height: 5em; resize: vertical; }
104
+
105
+ .toggle { display: flex; align-items: center; gap: 6px; color: var(--ink-soft); font-size: 12px; }
106
+ .toggle.small { margin-left: auto; }
107
+
108
+ button {
109
+ font: inherit;
110
+ font-size: 13px;
111
+ border-radius: 6px;
112
+ border: 1px solid var(--line);
113
+ background: var(--card);
114
+ color: var(--ink);
115
+ padding: 5px 12px;
116
+ cursor: pointer;
117
+ }
118
+
119
+ button:hover:not(:disabled) { border-color: var(--ink-faint); }
120
+ button:disabled { opacity: 0.45; cursor: default; }
121
+
122
+ button.primary {
123
+ background: var(--accent);
124
+ border-color: var(--accent);
125
+ color: var(--accent-ink);
126
+ font-weight: 500;
127
+ }
128
+
129
+ button.quiet { color: var(--ink-soft); }
130
+
131
+ .status {
132
+ margin-left: auto;
133
+ font-size: 12px;
134
+ color: var(--ink-soft);
135
+ font-family: var(--mono);
136
+ }
137
+
138
+ .status.on { color: var(--good); }
139
+ .status.off { color: var(--bad); }
140
+
141
+
142
+ .layout {
143
+ flex: 1;
144
+ min-height: 0;
145
+ display: grid;
146
+ grid-template-columns: minmax(220px, 1fr) minmax(320px, 1.6fr) minmax(300px, 1.4fr);
147
+ gap: 1px;
148
+ background: var(--line);
149
+ }
150
+
151
+ @media (max-width: 900px) {
152
+ /* Avoid auto rows distributing spare height to collapsed panels. */
153
+ .layout {
154
+ grid-template-columns: 1fr;
155
+ grid-template-rows: auto minmax(0, 1fr) auto;
156
+ }
157
+ .layout > .panel { min-height: 0; }
158
+ .work { min-height: 220px; }
159
+ .catalogue:not(.shut), .traffic:not(.shut) { max-height: 45vh; }
160
+ }
161
+
162
+ .panel {
163
+ background: var(--page);
164
+ display: flex;
165
+ flex-direction: column;
166
+ min-height: 0;
167
+ }
168
+
169
+ .panel-head {
170
+ display: flex;
171
+ align-items: center;
172
+ gap: 8px;
173
+ padding: 8px 14px;
174
+ border-bottom: 1px solid var(--line);
175
+ background: var(--card);
176
+ }
177
+
178
+ .panel-head h2 {
179
+ font-size: 12px;
180
+ font-weight: 600;
181
+ text-transform: uppercase;
182
+ letter-spacing: 0.06em;
183
+ color: var(--ink-soft);
184
+ margin: 0;
185
+ flex: 1;
186
+ overflow: hidden;
187
+ text-overflow: ellipsis;
188
+ white-space: nowrap;
189
+ }
190
+
191
+ .work .panel-head h2 { text-transform: none; letter-spacing: 0; font-size: 14px; color: var(--ink); font-family: var(--mono); }
192
+
193
+ .scroll { flex: 1; overflow: auto; padding: 12px 14px; min-height: 0; }
194
+
195
+
196
+ .panel.shut > .scroll { display: none; }
197
+ .panel.shut .panel-head > .toggle,
198
+ .panel.shut .panel-head > button:not(.disclose) { display: none; }
199
+
200
+ .panel.shut.waiting .panel-head h2::after {
201
+ content: "";
202
+ display: inline-block;
203
+ width: 6px;
204
+ height: 6px;
205
+ margin-left: 6px;
206
+ border-radius: 50%;
207
+ background: var(--accent);
208
+ vertical-align: 1px;
209
+ }
210
+
211
+ .disclose {
212
+ border: 0;
213
+ background: none;
214
+ color: var(--ink-soft);
215
+ padding: 2px;
216
+ line-height: 1;
217
+ cursor: pointer;
218
+ display: none;
219
+ }
220
+
221
+ .disclose svg { display: block; transition: transform 0.12s; }
222
+ .panel:not(.shut) .disclose svg { transform: rotate(90deg); }
223
+
224
+ @media (max-width: 900px) {
225
+ .disclose { display: block; }
226
+ .catalogue > .panel-head,
227
+ .traffic > .panel-head { cursor: pointer; user-select: none; }
228
+ .catalogue > .panel-head:active,
229
+ .traffic > .panel-head:active { background: var(--page); }
230
+ }
231
+
232
+ .empty { color: var(--ink-faint); font-size: 13px; margin: 4px 0; }
233
+
234
+
235
+ .group { margin-bottom: 16px; }
236
+
237
+ .group h3 {
238
+ font-size: 11px;
239
+ text-transform: uppercase;
240
+ letter-spacing: 0.06em;
241
+ color: var(--ink-faint);
242
+ margin: 0 0 6px;
243
+ font-weight: 600;
244
+ }
245
+
246
+ .item {
247
+ display: block;
248
+ width: 100%;
249
+ text-align: left;
250
+ border: 1px solid transparent;
251
+ background: transparent;
252
+ border-radius: 6px;
253
+ padding: 6px 8px;
254
+ margin-bottom: 2px;
255
+ cursor: pointer;
256
+ }
257
+
258
+ .item:hover { background: var(--card); border-color: var(--line); }
259
+ .item.chosen { background: var(--card); border-color: var(--accent); }
260
+
261
+ .item .name { font-family: var(--mono); font-size: 12.5px; display: block; }
262
+ .item .note { color: var(--ink-faint); font-size: 11.5px; display: block; margin-top: 1px; }
263
+
264
+ .tag {
265
+ font-size: 10px;
266
+ text-transform: uppercase;
267
+ letter-spacing: 0.05em;
268
+ border-radius: 4px;
269
+ padding: 1px 5px;
270
+ margin-left: 6px;
271
+ border: 1px solid currentColor;
272
+ vertical-align: 1px;
273
+ }
274
+
275
+ .tag.destructive { color: var(--bad); }
276
+ .tag.readonly { color: var(--good); }
277
+
278
+
279
+ .about { color: var(--ink-soft); margin: 0 0 14px; }
280
+ .about > :first-child { margin-top: 0; }
281
+ .about > :last-child { margin-bottom: 0; }
282
+ .about p { margin: 0 0 8px; }
283
+ .about h3, .about h4, .about h5, .about h6 {
284
+ color: var(--ink);
285
+ font-size: 13px;
286
+ font-weight: 600;
287
+ margin: 14px 0 6px;
288
+ }
289
+ .about ul, .about ol { margin: 0 0 10px; padding-left: 18px; }
290
+ .about li { margin: 3px 0; padding-left: 2px; }
291
+ .about li::marker { color: var(--ink-faint); }
292
+ .about a { color: var(--accent); }
293
+ .about strong { color: var(--ink); font-weight: 600; }
294
+
295
+ /* Keep inline code from increasing paragraph line height. */
296
+ .about code, .question code {
297
+ font-family: var(--mono);
298
+ font-size: 0.9em;
299
+ line-height: 1;
300
+ background: var(--card);
301
+ border: 1px solid var(--line);
302
+ border-radius: 4px;
303
+ padding: 1px 4px;
304
+ white-space: nowrap;
305
+ }
306
+
307
+ .about pre {
308
+ background: var(--card);
309
+ border: 1px solid var(--line);
310
+ border-radius: var(--radius);
311
+ padding: 9px 11px;
312
+ margin: 0 0 10px;
313
+ overflow-x: auto;
314
+ }
315
+
316
+ .about pre code {
317
+ background: none;
318
+ border: 0;
319
+ padding: 0;
320
+ font-size: 12px;
321
+ line-height: 1.5;
322
+ white-space: pre;
323
+ }
324
+
325
+ .arguments { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
326
+
327
+ .argument { display: flex; flex-direction: column; gap: 3px; }
328
+
329
+ .argument > label { font-size: 12px; font-weight: 500; }
330
+ .argument .hint { font-size: 11.5px; color: var(--ink-faint); }
331
+ .argument .required { color: var(--bad); margin-left: 3px; }
332
+
333
+ .argument .wanting { border-color: var(--bad); }
334
+ .argument .wanting:focus { outline-color: var(--bad); }
335
+ .argument input[type="text"], .argument input[type="number"], .argument select { width: 100%; }
336
+ /* Keep checkbox hints below both the box and label. */
337
+ .argument.flag {
338
+ display: grid;
339
+ grid-template-columns: auto 1fr;
340
+ align-items: center;
341
+ gap: 2px 8px;
342
+ }
343
+ .argument.flag > label { order: 2; font-weight: 400; }
344
+ .argument.flag > input { order: 1; }
345
+ .argument.flag > .hint { order: 3; grid-column: 1 / -1; }
346
+
347
+
348
+ .outcome:empty { display: none; }
349
+
350
+ .result {
351
+ border: 1px solid var(--line);
352
+ border-left: 3px solid var(--good);
353
+ border-radius: var(--radius);
354
+ background: var(--card);
355
+ padding: 10px 12px;
356
+ margin-bottom: 10px;
357
+ }
358
+
359
+ .result.failed { border-left-color: var(--bad); }
360
+
361
+ .result h4 {
362
+ margin: 0 0 6px;
363
+ font-size: 11px;
364
+ text-transform: uppercase;
365
+ letter-spacing: 0.06em;
366
+ color: var(--ink-soft);
367
+ flex: 1;
368
+ }
369
+ .result pre { margin: 0; font-family: var(--mono); font-size: 12px; white-space: pre-wrap; word-break: break-word; }
370
+
371
+ button.tiny { font-size: 11px; padding: 1px 7px; }
372
+
373
+
374
+ /* minmax(0, ...) prevents long keys from consuming the value column. */
375
+ .fields {
376
+ display: grid;
377
+ grid-template-columns: minmax(0, auto) minmax(0, 1fr);
378
+ gap: 3px 14px;
379
+ align-items: baseline;
380
+ }
381
+
382
+ /* Let each row's children participate in the parent grid. */
383
+ .field-row { display: contents; }
384
+
385
+ .field-name {
386
+ color: var(--ink-soft);
387
+ font-size: 12px;
388
+ white-space: nowrap;
389
+ overflow-wrap: anywhere;
390
+ }
391
+
392
+ /* Stack long protocol keys above values in the narrow traffic panel. */
393
+ .frame .fields { display: block; }
394
+ .frame .field-row { display: block; }
395
+ .frame .field-name { display: block; white-space: normal; }
396
+ .frame .field-value { padding-left: 12px; }
397
+ .frame .field-value.nested { padding-left: 12px; border-left: 1px solid var(--line); }
398
+
399
+ .field-value { min-width: 0; }
400
+ .field-value.nested { grid-column: 1 / -1; padding-left: 12px; border-left: 1px solid var(--line); }
401
+
402
+ .items { margin: 0; padding-left: 20px; }
403
+ .items > li { margin: 3px 0; }
404
+ .items > li::marker { color: var(--ink-faint); font-size: 11px; }
405
+
406
+ .value { font-family: var(--mono); font-size: 12.5px; word-break: break-word; }
407
+ .value.string { color: var(--ink); }
408
+ .value.number { color: var(--received); }
409
+ .value.boolean.true { color: var(--good); }
410
+ .value.boolean.false { color: var(--bad); }
411
+ .value.absent { color: var(--ink-faint); font-style: italic; font-family: var(--sans); }
412
+
413
+ pre.value.text {
414
+ margin: 2px 0;
415
+ padding: 6px 8px;
416
+ background: var(--page);
417
+ border: 1px solid var(--line);
418
+ border-radius: 6px;
419
+ font-size: 12px;
420
+ white-space: pre-wrap;
421
+ word-break: break-word;
422
+ }
423
+
424
+ .value-raw { margin: 0; }
425
+
426
+ /* Suppress ancestor copy buttons while a descendant is hovered. */
427
+
428
+ /* Scalars remain inline; branches retain block layout. */
429
+ .copyable { position: relative; display: inline-block; max-width: 100%; }
430
+ .copyable:has(> .fields), .copyable:has(> .items), .copyable:has(> pre) { display: block; }
431
+ /* Explicit display rules must not override hidden. */
432
+ .copyable[hidden] { display: none; }
433
+
434
+ .copy {
435
+ border: 0;
436
+ background: none;
437
+ color: var(--ink-faint);
438
+ padding: 0 2px;
439
+ margin-left: 4px;
440
+ line-height: 1;
441
+ vertical-align: baseline;
442
+ opacity: 0;
443
+ transition: opacity 0.1s;
444
+ cursor: pointer;
445
+ }
446
+
447
+ .copyable:hover > .copy { opacity: 1; }
448
+ .copyable:has(.copyable:hover) > .copy { opacity: 0; }
449
+ .copy:hover { color: var(--accent); }
450
+
451
+ .field-name.labels-branch:hover > .copy,
452
+ .field-name.labels-branch:focus-within > .copy { opacity: 1; }
453
+
454
+ .field-name.labels-branch:has(.copy:hover) + .field-value,
455
+ .field-name.labels-branch:has(.copy:focus-visible) + .field-value {
456
+ outline: 1px dashed var(--accent);
457
+ outline-offset: 3px;
458
+ border-radius: 3px;
459
+ }
460
+ .copy:focus-visible { opacity: 1; outline: 2px solid var(--accent); border-radius: 4px; }
461
+ .copy.done { color: var(--good); opacity: 1; }
462
+ .copy svg { display: block; }
463
+
464
+ .note-line {
465
+ font-family: var(--mono);
466
+ font-size: 11.5px;
467
+ color: var(--ink-soft);
468
+ padding: 2px 0;
469
+ }
470
+
471
+ .note-line .level { color: var(--warn); }
472
+
473
+ progress { width: 100%; height: 6px; }
474
+
475
+
476
+ .log { font-family: var(--mono); font-size: 11.5px; }
477
+
478
+ .frame { margin-bottom: 6px; border-left: 2px solid var(--line); padding-left: 8px; }
479
+ .frame.sent { border-left-color: var(--sent); }
480
+ .frame.received { border-left-color: var(--received); }
481
+
482
+ .frame summary {
483
+ cursor: pointer;
484
+ color: var(--ink-soft);
485
+ white-space: nowrap;
486
+ overflow: hidden;
487
+ text-overflow: ellipsis;
488
+ }
489
+
490
+ .frame.sent summary::before { content: "→ "; color: var(--sent); }
491
+ .frame.received summary::before { content: "← "; color: var(--received); }
492
+
493
+ .frame .views { margin: 4px 0 0 0; }
494
+
495
+ .frame pre {
496
+ margin: 0;
497
+ white-space: pre-wrap;
498
+ word-break: break-word;
499
+ color: var(--ink);
500
+ }
501
+
502
+
503
+ .views-bar { display: flex; justify-content: flex-end; align-items: center; gap: 6px; margin-bottom: 4px; }
504
+ .views-bar .copy { opacity: 0.55; }
505
+ .views:hover > .views-bar .copy { opacity: 1; }
506
+ .result .views-bar { margin-top: -22px; }
507
+
508
+
509
+ dialog.question {
510
+ border: 1px solid var(--line);
511
+ border-radius: var(--radius);
512
+ background: var(--card);
513
+ color: var(--ink);
514
+ padding: 18px 20px;
515
+ max-width: 460px;
516
+ width: calc(100% - 32px);
517
+ }
518
+
519
+ dialog.question::backdrop { background: rgba(0, 0, 0, 0.4); }
520
+ dialog.question h2 { margin: 0 0 8px; font-size: 15px; }
521
+ dialog.question #question-text { margin: 0 0 14px; }
522
+ dialog.question #question-text p { margin: 0 0 8px; }
523
+ dialog.question #question-text :last-child { margin-bottom: 0; }
524
+ dialog.question menu { display: flex; justify-content: flex-end; gap: 8px; margin: 18px 0 0; padding: 0; }
525
+ dialog.question .argument { margin-bottom: 10px; }