agentkit-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.
- agentkit_mcp-0.1.0.dist-info/METADATA +117 -0
- agentkit_mcp-0.1.0.dist-info/RECORD +8 -0
- agentkit_mcp-0.1.0.dist-info/WHEEL +5 -0
- agentkit_mcp-0.1.0.dist-info/licenses/LICENSE +23 -0
- agentkit_mcp-0.1.0.dist-info/top_level.txt +3 -0
- auth_middleware.py +113 -0
- mcp_server.py +326 -0
- web_app.py +222 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agentkit-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AgentKit MCP Server — Business Intelligence tools for Claude/Cursor agents.
|
|
5
|
+
Author: Yacine
|
|
6
|
+
License: AGPL-3.0
|
|
7
|
+
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: fastmcp
|
|
12
|
+
Requires-Dist: uvicorn
|
|
13
|
+
Requires-Dist: python-dotenv
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# AgentKit — MCP Server for Business Intelligence Agents
|
|
17
|
+
|
|
18
|
+
[](https://github.com/Yacine-ai-tech/AgentKit/actions/workflows/ci.yml) [](LICENSE)
|
|
19
|
+
|
|
20
|
+
Expose enterprise KPIs, health scores, forecasting, and anomaly detection as
|
|
21
|
+
tools, resources, and prompt templates that any MCP-compatible agent (Claude
|
|
22
|
+
Desktop, Cursor, LangGraph, Claude Agent SDK, CrewAI) can use.
|
|
23
|
+
> 🔗 **Live MCP server (SSE):** https://agentkit.ysiddo-ai-projects.app/sse — connect from Claude Desktop
|
|
24
|
+
> via `mcp-remote` (see [claude_desktop_config.example.json](claude_desktop_config.example.json)). On-demand backend (first call ~30–60 s).
|
|
25
|
+
|
|
26
|
+
## What It Does
|
|
27
|
+
|
|
28
|
+
- **6 MCP Tools**: `query_kpis`, `get_company_health`, `detect_kpi_anomalies`, `forecast_metric`, `list_available_metrics`, `get_executive_summary`
|
|
29
|
+
- **6 MCP Resources**: `kpi://Finance/latest` and similar for Growth, Operations, People, ESG, IT_Ops
|
|
30
|
+
- **1 Reusable Prompt**: `monthly_executive_briefing`
|
|
31
|
+
- **LangGraph 3-agent workflow** in `workflow.py`
|
|
32
|
+
- **Claude Agent SDK demo** in `demos/claude_agent_sdk_demo.py`
|
|
33
|
+
- **CrewAI demo** in `demos/crewai_demo.py`
|
|
34
|
+
- **DSPy research scaffold** in `research/dspy_experiment.py`
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
python -m venv .venv && source .venv/bin/activate
|
|
40
|
+
pip install -r requirements.txt
|
|
41
|
+
cp .env.example .env # fill in keys + POSTGRES_URL
|
|
42
|
+
python mcp_server.py
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Claude Desktop Setup
|
|
46
|
+
|
|
47
|
+
Add to `~/.config/Claude/claude_desktop_config.json`:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"mcpServers": {
|
|
52
|
+
"agentkit": {
|
|
53
|
+
"command": "python",
|
|
54
|
+
"args": ["/abs/path/to/agentkit/mcp_server.py"],
|
|
55
|
+
"env": {
|
|
56
|
+
"POSTGRES_URL": "postgresql://...",
|
|
57
|
+
"ANTHROPIC_API_KEY": "sk-ant-..."
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Restart Claude Desktop, then ask:
|
|
65
|
+
- "What's our company health right now?"
|
|
66
|
+
- "Forecast revenue for the next 6 months."
|
|
67
|
+
- "Are there anomalies in the Finance KPIs?"
|
|
68
|
+
|
|
69
|
+
## LangGraph Workflow
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from workflow import analyze
|
|
73
|
+
result = analyze("What drove gross margin in Q1?")
|
|
74
|
+
print(result["report"])
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Architecture
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
Claude Desktop / Cursor / LangGraph
|
|
81
|
+
│
|
|
82
|
+
▼ MCP
|
|
83
|
+
┌──────────────────┐
|
|
84
|
+
│ mcp_server.py │
|
|
85
|
+
│ 6 tools │
|
|
86
|
+
│ 6 resources │
|
|
87
|
+
│ 1 prompt │
|
|
88
|
+
└────────┬─────────┘
|
|
89
|
+
│
|
|
90
|
+
┌──────────────┼──────────────┐
|
|
91
|
+
▼ ▼ ▼
|
|
92
|
+
pg_store insights forecasting
|
|
93
|
+
(KPIs) (health, (LinearReg
|
|
94
|
+
anomalies) + Monte Carlo)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
MIT
|
|
100
|
+
|
|
101
|
+
## ⚖️ License & Enterprise Use (Dual-License)
|
|
102
|
+
|
|
103
|
+
This project is open-source under the **AGPL-3.0 License**. It is completely free for researchers, students, and open-source hobbyists.
|
|
104
|
+
|
|
105
|
+
> **Commercial Use:** The AGPLv3 license requires that any proprietary network service (SaaS, internal corporate tools) that uses or modifies this code must also open-source its entire backend.
|
|
106
|
+
>
|
|
107
|
+
> If you wish to use this framework in a closed-source commercial environment, or require **Enterprise features** (SSO, Active Directory, Custom VPC Deployment, Strict RBAC), you must obtain a **Commercial License**.
|
|
108
|
+
> Please reach out to discuss commercial licensing and integration consulting.
|
|
109
|
+
|
|
110
|
+
## 📡 Anonymous Telemetry
|
|
111
|
+
This project collects anonymous, GDPR-compliant startup pings to help the author understand usage volume and prioritize development.
|
|
112
|
+
* **What is collected:** Only the project name and a "startup" event timestamp. No PII, no API keys, no user data.
|
|
113
|
+
* **How to disable:** We respect your privacy. To opt-out, simply set `TELEMETRY_OPT_OUT=true` in your `.env` file.
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
<!-- Scarf Analytics Pixel -->
|
|
117
|
+
<img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=agentkit-yacine-ai-projects" />
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
auth_middleware.py,sha256=8ihKsL-K9gTJloiGqX0pk_T0drVvg7ZmI8VEeaYRlhE,91191
|
|
2
|
+
mcp_server.py,sha256=BFRGi3xeNtXptAsG8S7304vj8zwthfsZovIrFHXr8cM,13974
|
|
3
|
+
web_app.py,sha256=wQw7ee4p5PDidsFaRQixPInk2uUDLuHOdAENWOoZ538,9212
|
|
4
|
+
agentkit_mcp-0.1.0.dist-info/licenses/LICENSE,sha256=ANdl7_PYpqplg7PWX2N7AxXWJbj4uxBaJcnEo75DWVI,1150
|
|
5
|
+
agentkit_mcp-0.1.0.dist-info/METADATA,sha256=nwbHsp2_riMbHoB050FqaAZskLeQBlt8uUJrUoZ67ZM,4577
|
|
6
|
+
agentkit_mcp-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
7
|
+
agentkit_mcp-0.1.0.dist-info/top_level.txt,sha256=791y19RWE8tzYAXFVtNej8iKZJccUuZvo6qQvJme-18,35
|
|
8
|
+
agentkit_mcp-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
GNU AFFERO GENERAL PUBLIC LICENSE (AGPL-3.0)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yacine (OmniIntelOS / Ysiddo AI Projects)
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Affero General Public License as published
|
|
7
|
+
by the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Affero General Public License for more details.
|
|
14
|
+
|
|
15
|
+
========================================================================
|
|
16
|
+
DUAL-LICENSE / COMMERCIAL USE WARNING:
|
|
17
|
+
========================================================================
|
|
18
|
+
This software is licensed under AGPLv3, which requires that any network
|
|
19
|
+
service (SaaS) built using this code MUST open-source its entire backend.
|
|
20
|
+
|
|
21
|
+
If you are a commercial entity and wish to integrate this code into a
|
|
22
|
+
proprietary, closed-source system, you MUST purchase a Commercial License.
|
|
23
|
+
Contact the author to discuss commercial licensing and Enterprise support.
|
auth_middleware.py
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""Pure-ASGI bearer-token auth + per-client rate limiting for the AgentKit SSE endpoint.
|
|
2
|
+
|
|
3
|
+
Version-independent (doesn't depend on FastMCP internals): wraps any ASGI app. Gated by env:
|
|
4
|
+
MCP_AUTH_TOKEN — if set, requests must send `Authorization: Bearer <token>` (else 401).
|
|
5
|
+
MCP_RATE_LIMIT — max requests per window per client IP (default 120).
|
|
6
|
+
MCP_RATE_WINDOW — window seconds (default 60).
|
|
7
|
+
If MCP_AUTH_TOKEN is unset, auth is disabled (dev mode) and a warning should be logged by the
|
|
8
|
+
caller. Rate limiting always applies.
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import time
|
|
14
|
+
from collections import defaultdict, deque
|
|
15
|
+
from typing import Deque, Dict
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Small self-contained browser landing/demo page for the MCP server (served at /demo, before
|
|
19
|
+
# auth). A browser can't speak MCP, so this shows liveness, the tool catalog, and how to connect.
|
|
20
|
+
_DEMO_HTML = b"""<!DOCTYPE html><html lang=en><head><meta charset=utf-8>
|
|
21
|
+
<meta name=viewport content="width=device-width,initial-scale=1"><title>AgentKit - MCP server</title><link rel=icon type=image/png href="data:image/png;base64,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"><link rel=apple-touch-icon href="data:image/png;base64,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">
|
|
22
|
+
<style>:root{--bg:#070b16;--card:#0f1628;--bd:rgba(125,155,215,.18);--tx:#eaf1ff;--mut:#9fb0d0;--ac:#22d3ee;
|
|
23
|
+
--grad:linear-gradient(120deg,#4f46e5,#2563eb 45%,#22d3ee)}
|
|
24
|
+
*{box-sizing:border-box}body{margin:0;color:var(--tx);font:15px/1.55 Inter,system-ui,Segoe UI,Roboto,sans-serif;
|
|
25
|
+
background:radial-gradient(1100px 620px at 6% -12%,rgba(79,70,229,.16),transparent 60%),radial-gradient(960px 600px at 102% 2%,rgba(34,211,238,.11),transparent 55%),var(--bg)}
|
|
26
|
+
.wrap{max-width:820px;margin:0 auto;padding:36px 20px 64px}
|
|
27
|
+
h1{font-size:1.7rem;margin:0 0 4px;font-family:'Space Grotesk',Inter,sans-serif;display:flex;align-items:center;gap:12px}
|
|
28
|
+
.gt{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
|
|
29
|
+
.sub{color:var(--mut);margin:0 0 22px}.card{background:var(--card);border:1px solid var(--bd);border-radius:12px;padding:20px;margin-bottom:18px}
|
|
30
|
+
.pill{display:inline-block;font-size:.72rem;padding:2px 8px;border-radius:999px;background:#1f2937;color:var(--mut);margin-left:8px}
|
|
31
|
+
.pill.ok{background:#0f2e1b;color:var(--ac)}code,pre{background:#0d1117;border:1px solid var(--bd);border-radius:6px}
|
|
32
|
+
code{padding:1px 6px;color:var(--mut)}pre{padding:14px;overflow:auto;white-space:pre-wrap}
|
|
33
|
+
.tools{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:8px;margin-top:8px}
|
|
34
|
+
.tool{background:#0d1117;border:1px solid var(--bd);border-radius:8px;padding:8px 10px;font-size:.85rem}
|
|
35
|
+
.tool b{color:var(--ac)}a{color:var(--ac)}</style></head><body><div class=wrap>
|
|
36
|
+
<h1><img width=34 height=34 src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAABrLUlEQVR4nI39ebBnx3XnB35O5r2/7a1VBRRQKACFfd8BEgRIAARAiqRWammppbbktt2OjvaMPZ6ZsD3hCTtiPItjonsiJsbtbo1DvUlqtaSW1BJFgjspESS4gtg3AsRSBaCAWt/+W+7NzPnjnMx7H9URnkcW6tVvuTdvnu171pQjN96bxCVIAiIIgjghSQIBEQEEJ0JKgohDnCMJkECcfl7EgUBC/9bvOnD6XRzkN5xAEgd2bf1LEBEiKX8ZvYWAJFxKJHEkBJFka9H3SPoaAMmBRLtG0iskIYktONF7T3+XBCmV5ennSLp+7L3yVtJ3JSEkSI6UEhDtQ3qfFBOSnylF3Su7Y8r/EfQaCCklRNB1poTom5DQ/QOi0z1xIugq8v3ytbtnyq+TEuLEHj2V1/UOiSp/DnF6EbE3jSi6DgGU8E50w6IR1TlH8mIMYYRzSnwRwDlbnkNcIjkBvG68o/sRIYkzPrGHz2siAnpvUiIJOFusbp8UojlxpORAkr5qa7JtRpJ0RCLqbZLeLwllYzPzuSR2Zf1xhQEoDLV/8/Xv5DqukWhE7ROlXCMTuaOnlDc6eiIqOJmHxYv94jpmytfYz2pkwjoT8ERUGieolMBe35DUEUVAkjNCdRIeTYKddyTn9DvibFEO52wlToyLBcSX72PSX7jY+7I5ukHONFA0Rkn6mvj9D+WAmOw6UgiR8r4UhlRt4HB/Y+OdMUWynZf8b1MQYgxWvoeQCPbdTHbTNgliSnofokmbfsKlBDGBU23hTN2Yfsn0y6yD6WGyFtL1JVu37uM+AZDeerIU29WigDPBT0VgnNEmUSmxo0qby2/ajZypaVEVKiIq0M6ZShUQhxOnu2mfl8wE9h1xzkyDw4lxrzjbLGP/snDVLCIOwZkJ6NRnn8PF99Sz9HS4mYUi7JjJsG+KmIrNnzHDkwkpEgt5VN2lsoaU+moLJCmjSkp6Hd1pvFEjuWhUMLOR9H6m74FYVHynSXpPKxTNUWQzf16yadMfJ9kQZfZJJvWmJzNf9P6usshne6c0UaJFSYWgDmUQnNObmHp2zpGc4L0v0q3MpETWa/rOLPSZA8MSgqrurCXs+uVRJNmm+YI7SFnClKyORCqP3T1DSlE3Km8SqWya6g6TWBMlSck+FctanMuEyYYk9uQ0KQZIyiyOREoOSXpvJIJzypOEsl6ldQQqcHp/kU55F7JJ4fDyzJI1QSGqibgzDZSfJTNUFtakGr7gN6ASZyo3gSMDGgNbJpliNjmZ5IsowVXCnG6w90XiMfBXmEeqci1dqGoKxRpZa7hOYxSbneUi2n2d/UuUIVxW2/kBQSUqFUl1VLgE0WXGV1PnUGL35S05OgCmdzXmsjWYunFJhVqSWaIMAFMipkhh3ZQZJhgdfHkmNTUZfVYm1cpIRloCsUh7wa5lf7rd6XBc+Y8SOmXhst8LRky290IlRLX1ord1Jp3RAJ7YFToCOTMDRjznEGfSb58TBKkqMx324ALJ+eJFiDMTk9Ss5MVGuidS6JcNXrbQ9l9xdDxexMJUuwlIKoxva1EV7Ip0dChAN8mkpWgWDEIYDulpAJIuNqLeSX6ArM5TiiRjWEkVONU8mXSZ4FK+29EvRSBFvGEiCuoPhglcEQOXGcdlLy11Ul88qWTyYe93tpHK4e2CtjhT3SqwgnOO6CCJR2lmi3K+MEYy4CZeia1mwYPzutlOEO/tnkKIkTYEYowkV+Gcx1cD3KBGKo94l/UuIYndM3XgjrxnSqzYR9eSXdRUPM9sF1NKetmUiNksJJXUIFnLpmKWVCCNWURduVhMDKpBTBNgrl4GYar+ddU+6wQxNjLtWLUtcWsPia1ZXoFhjQw9kWjArX89M8lG6FjkPRWQrfRNhcEUQOtadfNiz4WGqjCDqe4kJt1OVXUw9exE8F6I4hBX4ZwBv6yavRIu+/7iHM57xHliSixCoAFkacLk4CFWDx9m+cLDTNYPMF5eZjAcQ+VVo4j5+kjPXmeZzDY8KQEcHTYQk4SohBR6vngmdlGX+t2MAjqEZK+47IvnL6jLqMCxMxPKDtHuZ9pCssehm+7sj5iLnJJA5WnOnuWHf/BvGcwd3jlmzZwr7ryGY/feSLOI4LzijQghRcMbmTOjIXwx5kymvKSgIdcDt5mnszeRMXOF2XBV4Sjhsm9vOMD3Vbbz9rcyiEp9hXPmKfhKXUQRmhBoYsStr3Pw2BVceN01rF50lHo4ZjGdsn1+g61zG7zz2nGm2zssFjPaJhFDiyTd1EhWydnnztrAiFXENUtf1v/qosm+1xQ7ZLevqPokRDEiZyBooE4hUWY4EBzRDKoTl/VB0R5IKi6XmHAA5r0pkJ7P5lx2+w3cdv9dRO9wlVcc1ib8Us3G1iZf+bdfZliPVFtlu561N1n6OybP5j3bPTU9yiTFLO77lK6zKjbWAjdiqB4RvLgi1cmbyhdVyc5XiPfgDfk75eKEY960NMMhK9dcydW33soFV1xFCImTb57gja9+kzMnTjA9c5awO8W1hmxzkAmLKYgU4AuOJKFE7HJoRkxtKvZTm2sKsweIuofOUTGVVv1stN8VkMWOKco3TVRyxJFeFC5r1R5bZrOUn0MjfBaNRHCVYzbdY21tlXTfnUoo19MQJBabu5x56QTjemRBLa84pQiD4q1kqF49jL5r2T1vF/PImqG/VqjIkuu6P8m0QvbXU1WrVhCH984CPh7x3lzACnGOeduwqD0X3HobV9z9QUbr65x6622+/e8+z3uv/IhmYxOfHIOqYlh5ZDDGDQzR03MLi73CgExv21OyTe0/Rv7pyFaYw6Q5C7xitWjvZ/oWY1tgXl91Yp+NGW+RvQApMYWYdWrK+NP1In0RQc2U8wnamkHlSQGz3cn23CkTtpFhNWBYD4hJtW7h506ZdyyXzVcOgZcH61zIvihI6natSm6/65ZM8pzzqhV8xgMa/XO+wnmvusM5nK+JMbEnsHbTjdz54YcYTFb50ZNP8+p3vs/2uycZtC2j4YjxaKLcnOPeSQFJMnUr5nunvv8SM3NI77kSUbIUJwNEgqRotq3n3JlqT5HutZRVdn+zOp6LqcMdCiAN9TvVBKm3z6mnWpNJugLFDNGy3laQGEi0sSWEqAEmMAdMCZsixBiJKZBMsos85FC7BbAKE8SEF2drMeOQMREGcvuCQfdT5TCvElkQ583e6+855Ou9h7pSDOA9rqpx3jONAX/4Am578GEOXn4FL33/KV74+uPM3z/NyFesDYbIcEg09Z1S2EeIvLH9Byq6v9hi88n7wXOLomXzlkO42cfV2E2yj6aixTXGJ6T+Lpjqtf+Xn2hIv7hUeb3GY0bTfbyWE09ijFnwSEoWLdRnSzERQ7CgrMeJB1epxrUbWIpCBaO4QPITEi0a9zBWzXmQTjvuj3Xs/wdUoAyQnEm9E3X5fKXhS+cVzVceXI2rHFVdERC2U+KSuz7AjQ99lNPvvMdjv/0v2HjjLZaqIaOlZZPwRExSkm8ZiRKVcilHm8v6zN8uqFx6tjZfxOFTfrxOirvvGR/lK/TCt13iM4tvR3j5ic0p3lH/hdR9KGXAl7r79Z7SopABksZOkjGIBtqCfswbwbzDVx58Z7ZS1OeRkinqUzE/vexjWgMERaCywchZRuzZc1Crwuy4qnOnElJJ0QKuqpBKipvn64pFhGZ5mVs+8UkOX3Yl3/vi13jlm99m2EZWx2Pl7hiNsMaNph5VUrNtlRI71zSrqcre0gvoS0nTobbRsTxgZ+vUvOdN0c3rCNttGohqXwc+SzFd7iCbIOVBBVcpJXqOd3etstPRYGk0LdAliZSg5lWlhEuxMK3z6nU555F6rpKfTDLIilB6DLvPmlNcg/Js9jRZfZSXe/vU45gqJ2vE7L9z6rsnB97cEyV+hasHzEKguvhi7vv0L7G3t+Az/+R32D7+DsujEVJDiG0nfdlFswhcXlCMqePbmNGrSmrKG5lyft3crmxOQyIHRPTZUlGJhbwpq8NubzQyZ5HFZI5VkBzE7Uia+r8LIkqsbOsl5bvasxmDUDRUxifGwMYcquooKWcxj8TXNS5qLsRZHCRvVHmmHpBNheBJwUPMz5pd3mwT83fETFXsacfMDEKVvPr56k+YHTImwHmk0lCvq2pmbcv4imPc+0u/xusvvcq3/vjPGC5aVkdjmhRxKfbyCT0utb+zNSrEL/um2UiVGpOOoruCqcC0//WfAFd9NdjhuhyPz7frS0/3evYqVFXq/bMWST2CC7EjfNFsf4NrSMWV1ecp0YeUiN5svDGpqypcSDjncXGgGMw2RnCq6UwTdRHbjtA5vKtmrktg7VtPZozsOUk2RVD5nKv3Frp1DryBQe/AV/iqYtY0TK65ig/80t/i+Se+z5N/8XmW6yG+rmljs39Ps1Sk/ZtdWKFn33OcuqsFsmok27bOBid7QEsR968t3V8UEFSoXmxv/0r7LbYBMygq4286mP1n2f/evmc3LJIytpDuuVT8NWpXEkt1RZXjK7FC6gEpWtg5lfqobAtsJUJfwytruJ6W37/GDEZTVGbsSJPUC0heNPTpBLwla3w2DZ5p0zC64kru/vlf5umvP8Gzn/0CqyONUtFEy0Nn4NNDQz3pyEmIvl7o9IH+5nJsvWx3Bm95G3KEqx8Hl6JxcjpYJTiWrzoL36afoFvPKv2v/PyvfbJ7KjGzUFzEfdU9EVJlGkIl0nuPF33WqvJ47whd9gJv0CMmV/CJ5LoCcwdTSp1ZyTvRN5EpJ6WkByF01ytV+5bVq7LKV2AivmbRtlRHL+GeX/hFnvvGEzzzl1/gwGhJa96sOmZfHl5yWZYxgrFbSl08ui+B+9WZ+4l3+5vbT8Lkr0Sc5nDtfzkWIGZyk3mC8u8lX07z/2QF1v/fPz1TpJrL4hpi9+7lDLSmpAswaQhCNGsaNJnj0qBUYTnnca4ixljulfMa+bmUqHQJMIA+E5CBrGoAke51WwWVZhtFEzwWEBJfI1VFSIl4cJ0P/Oynee2HL/DUZx5jfTTRxESypMy+OHS+bF6LdJwpP6FEDaEVTu1jmz6QMfVc1KCI5QdyWDM/qO9MT/7MftYsG6T2OQM0equCfiqwi/N3btO+n6wYUs7t9y5TTJwUk6RZuRYhqv8vqNBZltVTa3g9NOT0vPSeg0BXa5ggWl0DMfW81d7ni9XQIFs0UBhNQwlQiSV3xEuR/lywMfeOOz75M5x77zTf+5N/x2o11AgVWC2e70BWztqlpLVxSRDXqU5FqV05ithexx5b9Emm/8/eg17DW/w7hkC7iLQxEuKCSLY0sUidoKHV2ntqr7EM72vwonmDlCwwlBNAZdvK/Qto+vcRfx/fJK04IYHkQJf+6bKSWmWkKjuS7L6Vzylzj1RJXe5WmSaa7XbFfweSJaCyp9PzQDpGtfxGYQmxNIcxo3RQsjAA3pO8egBVVbHbtlz5wIMMJqt86Xf+KZOkBSIxJavOtfsKisRLcYX9N0tz3ovsHZSEDLaQ7P/3r6m/eCtnju2C2XzBIraEYcVkdYX64EHWDx5g5dABhqsryHio6WQB2kCczlhs7bF17jy7Z8/RbGyyvTNFZi0DqRgOBpqFS4EYtT4gW81euudvULvLQ3TMUqQ8J5Z6uYyMVvphiJSCaQMQX+Ocmk2fqpIOz6QrzEinyXKCTJKFpW3j+t5XFxa2S1gpPbG8YBjA57x9VXz+RYisXHEFl998O1/5/T8int/Cj8eE7C4FKTY4WfpUStVq5nyriMm2z27oJMfvXR87lUBHzkiG2LC3M2XhEsOD6xy47QYuuelaVq8+xuSyowwvOIAfD3G1ha6lx5D2jC5CagPtdM7s9Dn23n2Pc6++wbsvvMLZN94mbG4zkorBcIgTIYZQWLjLvStDpn2BlU7q9MdcRzG8If1Hc/lqZiKsGNaqsJz3uILOrfws2+woHWGtMiknh1PqzExRWD2AlFLoLVc6zZs6rSFApWBPOU9LtiAMR9z44MP86AdP895zL7E+npCicqnWO2TVllVnBiMoEOqldct+ZSER3ZSiIbBCzQTeVyzahr3pHm5tmYvuupUrPnQXh269keHFFxGHnlYSTduwF1pSbEnzRZEVSRo2LWUQhgfc2FNdcTEHrrmUCx+6h5vmLdPjJ3n3qRd487s/5PTLryO7MyajMd7VhNAWlVuAp3Tp5w7K2t8xu1YCZPua1XEkJWcC4nSNKTO7RWBzqXcKZA8oY5tYJLxDq1101ThB+nV/ObmXTVfnOeXcVx8IVs7XWpblPVU9YC80HL3rbkSGPPulr7EyGBZEL0kDIaXwIfNYtqUxo2/9cU7KBnbSYAuItiC0rLwJDVvzKZPLjnDrAx/iqo98kNGxS5nXnlm7YNYsYA+QqOEYNeBau1CKTLP908cOUSXGOyHEwHyxULvrhOGVR7j62su4/ucf5fwrr/PyV77Jm9/8HmFjh6XhBCeJEFp9pgzikpViZFVTACVWl2ASFrMHYOqYVGxwUXxGiMpXODOhzid1vTMiTpnAal4yFIlFkMyUFnDcA38FPtID4/tWBIhVBHmN+UcSwwOHuOq2O3niL75A2tqjGg8JUZH8PruY8nbnKJTaGeL+hUhSbaeARl00TfeYVDjH+ekuo4sPcc/PfozrHvkI1eGDbDcLNhYzQqOA0+JcyrVVTe0rBXdFHwq5oEOsTyE5CBHaGImhpY1aaURyzBYLZvMZznnGt17HR269njt+4RM899kv88pXvoHbmbE0HGvFrzFrMLeX1F9N4YWiEUqq20ShhHDVCJoQGaNYtlWBqGqPYMSOmVgxe0tWz5cxQSZ+z3DRvZSzzeQkWUc/Kb9V+JwI8sxi5Jo772Hj/bMcf+Z5ViZjUoylmiTbI/VFM5DrLlYu30+EmORklae853CVY97MmdaBG37uUe785Z9leOQwm/MpzfY2eNGqWFO/g2rAwHuYN8zObLH33ilOvXOS+ZmzLDa3aaZTQqMZtqquqZfH1OtrTC4+zOolR1i+6CCjA6vEQcVeaJnPF4VAe/MZezExuuISPvhf/Edc8+j9fP93/4STT/yQpcGAuhoQYkT1lRGiyBIQTGotUqnacv++iH2vLZrKNIn3hgsEVyerxMZsecdkavN/IspZ9rtT6oUPe2QuQLsHTgsDKPCrSEB98BCHr72Ob/zpZ/AhgKuLutfEQ0Jj0hmuu5Ic6e5msfzUBUK6XLVthXds7m2wdNVlfOo//jsc+eCdbDQztnc28VZJ3MZIPRiwWg1he4czL/2IV59+nvMvvMLZ42/Tbm7RzGYlOyiF/3U9EQg4fF1TL42pDq1ywZWXc+HNN3DJ7Tdw4bHLaCYDdpsFi6YFJ+w1c7ZDZHLj1Xz0//Jf8/pnv8yT//LfMN/YYnmyTIjdnUSyfe8BrGweSxm7SZ89d5SEiLqAOVUuzhtu02YSrQiPqrokdBFge66+f0DGPPYhvU2ndcjMlFQjZTOZYrJKa1E30DvPLAaO3XATG2fO8+7Lr7JUDwjmrqg0m1Qbis8eh5QASA8Zp94iywLUA4ip5exsytU/9SD3/Se/QTq4zns72zgPeEcIgcFoxJqv2Dt+khe+9T2Of/tJNt48QZrO8CQG3jNxHj9ZMf/abLRB25xL0Ht7Upto3tvgnXfPcuLxp3hmZcShG67mqo98kGMfuoPxRRewOZ/ThAbnHLuzGTsJLvvlT3LxzdfzrX/8zzjz5HOsTFYJKRJCgJTwVU1dD0w6M0DsOQiSEXhemyDZCwgQgzJLrheMTtPxbRuIbQuiYePCSOZqk/MLqdf5JBTCtu2C2XRKjK0Kh1SMxmPquiaEjnElJSpniN4tLXPR1dfwzNefwE0XyGhMSm1nUHqcl7e7aIMcwo1JNYDZZbGgRUoJ76BpFux64YP/yX/ANb/4Sc7HBXFnm7qqCbGl8p7VyTK7r7/Nd7/wV7zxre+yOHueoRuwVFf4pRUkBlLSkqlIQHJbF3Spz+ySiANpAYd3nuWqVtvYBM7/4AWe+O6zPH30Qq55+D6u/tQjjC+5iO3ZHjGpD7Oxs8Pk6sv4+P/9/8RT//wPeOmzX2FpbY3BoTVcXTM/fZ7zp86zNBxTVY5Ygl2mD3rgjOxFZC2R8xlOkGSNr2IFOTGRQiBKC6JFul3pR5Y8RxRLAZt995Vjd3eLyQG4496jXHhkHfGOc+9t8dqzJzj//jbLy+sgvmjuKhkCX7/0chZBOP7iy4zrSomfBTire+NsSV3Bxf5ihK59SmIGfuoNLBZz5ksjHvkv/zMOffgDnN7ZoXKKeueLhvXJBL+5xVP/+i94+YuPE8/vMBkOGI7HSFDTE1vrBhZbjWj83SHkLpyEBqxImqnIDypEJAarHUyMa8+4qlm88z7P/rN/w6tf+Co3/8rPceXPfoLpqGI6m6pmXMyYDx23/YPf4tJH7mdtZZXJwYMk72k2t3nzWz/g6T99jPbsNqPBoEgdphF86nCMJmXUOKVckyC5CUYQqwAiRK0GiirtDkfMBCdrlGz1FZB659iZnueOBy/n5/7Oh1k7PKR1C0KM+FSze2bBl//4e3z7Sy+zNDpArv2sJAkNcOiKK3j31dfYO3uOtfGYEGPZ0Ow+5FZwpHPjOp0gZsey0lBOdSIsZjPaA8t87L/5L1m+7UbObm9TeZUYQuTAcMLZJ37Ad//VH7L11rusjJepJiNiakmt9tWpycrt6MnK181DyMArR2P77mlU/ezsd4lJ7WFKxJiovGN9aYXFqU2++//5HY5/6/vc8/d+kwO3XMvGbFfDtDGxlQJLt1xH2zacXyQigfqCNW749Z/lintu57H/8R8ze/Mko6qGpCYiuUSwAJGKu9phzfZa+sqZmhfLWNKZ0oSF1KOA6/oEu3S6oh3vPLvTTe5+6Gp+67/4GLNwjq3pDt5p+/Rus0W1UvEr/9uHWVof8ZU/fIrl8UFSirgkiXpljZWDhzn+/AsMUoBkjRkxqJpPESzLpuDO3C28NjyU+QG5wM+qYgQWixmL1Qkf+2/+90xuuY5z29tU4gkhIs5xIAkv/PPf58v/wz+keesdDkwmeAKpmSMhFg2TQKnoQLzX2sTKUdeeauAYjBzV0FGNHH4kyMBR10JdQ1UJuU8s986FGG3DNe9eVQMOTtY59+SLfOG/+h94448+w2FfM8AhMeFFaPem1DgOLY05vLzMwDvObW4wuupSfur/+PcJK5bLt/49CTnoo/0H6vrFoklJXeJNfKWAsOQfYmGCYIARc/uSZVeTqLZrmpaDR5f49H/4ALvNOWbzlpXxQZrtitl54cD4IC7Bxu77/NSv3cv1d1/KbLqDw1G1IbB84YW0i5Yzx48z8J4UIiXbJqBtzQrgckSvjwtI5T/m6nkciRhbZsMBj/4f/nPGN93Axs4WdVXRhgXDwZCl7V0e/8f/X95+/HscWFoG54htS+5UKoi7MBk4L4hPeO9wXnC14LyAN/fUvJ0QEgTBtRAbi4p5iG2iWK/ivJiGi7C8tEzbRr7/T36fMz9+k3v+wW/RLg+IzYKV0ZjF62/zvS99AxBu/uTDrB+7hI2tLS688Spu+Oh9vPhnX2V1sgS0hu5jx7xJBcWZzY4kzf5ZSbdIRFw/1ds5mxLVsRdj5GiJNUGYz3Z54EO3Mjno2dxcsLp0gCe++CJf+Lc/ILaJ2z50Ob/4Wx8GdsDN+cinbuPVZ75EckIVUmLt4iOcP3WKdmuL0WCgKNc2U02OFXRm1ZSwcK9Vm0vCWoRIEpVYCDsJPvqf/accvvs2zuzuMvAVTYhMBkOq98/w1X/0P7Hx4iscWF0lhVhAU7L6/mRBHYnWjSTarCoVVAPB1w5XC1WtGkGl3OrvQ6JZtKR5nkkkQLA2OiFGnX9QsoBOTV1MCVfVrA9GvPmtH3Dn3/pZBqtHoYbF8ff4y//+H7E4cZYEvPHED/j0//P/THXBQWZN4Midt/LCZ7+uaNxCuCn3kWcBtgYbZ2heaoekCrKZoFVeyTLVg1mCRRRTRJzWAcWouOLIsYNMFzN8PeS949v8+e99G7dYo6prvvHZVzh29RHu/cS1zPf2uOTYYZYPLNNsJ1wcVEwOXcCZt99FWkXMkr3qlEhRAUmnggx4RGugSJR2ZrCKHu/ZmM+4/Zd+lisffYCt3R2GXnAxsDKoGb53hq/+3/5fbLz0Gisra1r0kPsNhcJ4Jd8vSljxCVeBHwh+5KnHnuFyjRtDqBviIBCqltY3uCGMlgdUY4cbJnyNVjv7pKXARpFoQKz0R5pb2bYLVlfXGS8t0baB8WjCa098n723T7O6vsb66gH2TpzirR88QzUcsNs0DA+sUVVCSo368BYOFgOERe04gwQiVJWjqh2uktJ9LSK52bhEgqWof/O8EkiMEBokBapRxaJtcd7z/rsbLKbCsB7ixTHyS5x8+xyIV9wz8AyGNTElqmq8xGA84dy772gbc9K4vkuqYrQAIVnwIlekZI6EXLYViZACXgbs7k05ctdt3PZLP8fZnU0cQmgDo7picG6Hx/7RP2b29vusrh7QeLvkahVKtipvnOrCqJIvCVclqoGjHgr1pKaVhoOXXsixG67iwOF1hJatU6d5/bnXOf32OepRrfH8oGq0DWIMJ5kKJYmCaZ3cqBNiSxsDEW1nH0wmpNBC2xBDIrUzhqMBi2ZBmxLNfA7NHFJlSWBPcrZ3aIIsl3u7XIjr1e57i5M4ry6ew+2LJiZjGBFn1ViZBpHURHa2ZsQk7M7mXHTZBSytwNa5Dep6wDxsc/X1R2nmc5I4mlnLYtrgXEU1XF5FxLFz5hy+qi2NmIjmXmkc3ILBFg+SwpJdvUqevtW2LbI24b7f/FX2HMTGql8lsbQIfOl//h12Xj/B6tIqITQKHsn1fJTNwoiQW6rFJaRyUCWqGuqho60Dtzx4H7c++CGGywOSzKnSnKG7irsfuJ0nvvhtnvqrZxgMB6QgtCGBF1zIGSvR2QIZaAplKph3nr3NLXZOnWFy0SG2dva44sMf4PW/+jbvfe9ZCA1H77+LQ3fdzsbOLivjJbZOvMNid4/JZFm1Zuao0kASSW4AOJpmAZKKadM9TwwGnspXqjF8ZQDcDEC0kK9AjEon5yrms13On98kylH25jNWDw741X/wcb72F0+ymLV88KMPcd09l7O7u8Hq8ho/+vE7bG/OWBqsU41WV2kWDc2uumZZptV7UrelVLmar1UCLyayOc3gq4qt6Q73/NyvMr78YjZ2drWpNLSsj5b43u/9Me/+4BkOLq3QNA2lZi+7lil1gRxSsX24HHrSGQW+EuZxzi0PPcItn3yU7fkuO9MpXha4NMMzZzRMPPQrH0GI/PCrz1CPhoTQ4gKkoFJk8ZkSrBK8qd2AR4g7e/z4q9/kg7ffzLlmlzgZ8ZH/9n/Hme89jQhccPft7A1rwmLOKASOP/4dqii2d5R909FyundehEVYsHb4oHpazhpHBaphYhDh6cd/qMKYc04FRkiJA4Fim3Obp7n1oeu5/cM3sLe3h3MVu/MdLrv1Av7jW3+GmCL1qGJrd0MDbosBj3/+GTxDSJFquLrGbDalnc+onTfwYc58ysWGsUMkdMEI/aiU7Nt0useBq45x9SMPsLm7h4gnhshkOOat7z/FK1/9OssH1pknSMNc+WI19AbgxFK4GuxS1Nt6QSqVeiYVoYILrrqCqz5yH6emUzyJynvA4aQGibRpyvZim/s+dQ/v/Phtzp3YoR4PiKkltgoGJUIsrYoKZpIGDwghMqkHvPrY1zh69x0ceuhDnNrYwNcV649+hJQSW9M90nzOxesHOPHYV3n7O0+xOhqTm14VViRyfMeLsLG7wbUfvZdbP/kIe9MZdVWR0oKqCqyOh3z99/+St559i+XxsnpEBf71QHjUpNHmzlluevBqfuF/8wkWflthmNPNnIUZMbQkItI6lsZLjOIKf/rbX+XNZ06yPDlACg3VcDxhvrNHWjS4gScUWe9lnqSTluLukWtTopqNKMzbGXd9/FGa4ZjFbIb3yv2LecPS0SN8+r/7r3Hed3VsTmsBUhkgZUEOZ6DTZYihiaXKJZwLIInR8pAtV5FSYOCcpnlFirciOAgLJksDbrzzah5/94dUwwHNrNUWuCaZ8UodBiAUbQYabBo28I1/+D/z4fmCix+4j5lLNE0DKbE0HjOO8Pbnvsx3/unvMqkGFozqaa8SiUxsbp/n6oc/xO2//NNsxhaf1MX2g8DqaMBf/8Hn+NHjz7E6WaENGoa3gjIFg+ZdudqzuXuGWx+6ll/4+x9nKttaWez0uV1T08waVg+sgUCcR95/fpOv/8mXefX777C8tE5YNOCEyg9q9rZmausLv3XVPJDtfkf6MpVD0DwCMJ/NOHDdMS66/RY2d6eaPAz6kK0EqkNrBH/Qat6lK0tyaM+fQX/9K1m/oiDo1C/nhCAJkYB3kSYGXApUlmAKoq5qRM2IE49HI2GHLlqnHnqYZxBrxO/Z5pw8T9kE2uuDukb2Fvz1//j/5tjXHueyD93F8KLDCLD9/inefOL7vP39Zxj7Ib6qzatQgivW1F3d3Nnm2kfu45Zf/hnOLeZa7ygJGQSW6iFf/92/5OVvPsfaeIXYaDmXykCO+WsdgK8qtvbOc+fDN/Lzf+9j7MYty9MJMTlW4yr/7rc/z9svnODIlZciImyd3+TU8XPEuWNlvKoTWEQBaSW1p5nPOgiewYuY+OVsU7YAxTnVTXTG6ovUctVHPkIzGhAWc1zS8rIm6vfbNo9KMyPmHE6Stj45Z6FeK19y6n2Is6FOYnEAF7UUWiK1SzgbURsQiGJVwxo3V8DqtADb6/ejRc7E5ywn5TkoSL2r3gGNC9S+YgXHO9/8Pm9887vUoyEAzXzBIAkr4wnJAJuUfQvkApitvV2uffTD3PSLn+J80+C8EFLE+8iSeL76z/6EN594idXVVQXRBrKcZVhzBsH7iu3dDW7/6HX83N/7GLO4aSXhFaTIslvhL377yzz3lR+zNF7lte+9q66e9wwHa7iJEFOb7S2JROXEEYw4JJ1zl4sXSs1+ZscEuRhC1xaJCLFpWD5yhCO33872bKGuZIx4LyxVNcRorpVG7TSgY5dzvsT2MSwgNqApRwBxKqlOIs7pHySwCG3Pv1bia9eNIyZHAwQnbJzdoW2STe+MZiYiToKCWmcAK8c+bP5gDsnlxtLxZIkJWK4+wXjFbHJEWg2edV3B2jG1ubfFdR9/gBs+/UnOLxq8QIoBEWEVx1//L3/Mm99+gfXVNcJ8oS5xRn3Zi0ConGdr9zx3fuxGfua3HmG33bRwsZqFlWqdz/7Ol3j6669wYO0CQkqMBlVx1WNKNtsoF6SCRNExcUQNV0bjvEzwgv9T5/Dps9nnkuAdzBZzrrzlZlhdIc5miBOquiIeP8G3/+JzVrShYFHKEAqxWr6uq0WyfjG1KQLJBZzX+9S1UI89ybUcue4YNz36MNthUWxjjo8nHG1UNT6fJ3780gkkJNrFgpiiurheiK1YBrZzZ1O0WUnSw8JROm8B1SZS3LJAKRCR7NUkvMDm7g7X/dQDXP8Ln+T8fG6VVcoYB3B8+5/9Ece/8xwrS2u0TWs9Gbk7uku8OSP+HR+/iU/+3YfZbrZsGozGEJb8Cp/7F1/nh197lQOrFxbwmFIy85A7uFLZ50znKoEFFvSGroSgLBpolaylRCn6EgPQSGEijUZccstNTNuGZKnMcV3x4lf/mve/+g2WVtaJMfSaGGzwVJ45iGCxU3ILU160CIjXpE49dAyWaoarA948eZyjl1/KBbfczNbupgFHdSlbp5Q7NDnAS996mrdfewefPHHRIG3SCBoJX4mCJxJ5nlCyMXMxGHQ3E6X7QSk/1OFS2gcgJJq21UQQ4GvP9myPax+9n+t/7pOcny/o5iLDWnJ891/+CSe++1yJhJZpYtH2OQnJaQBsc+s0t378Zj72mx9lc7ZpO6Yu5cQv85l/8TWe/uqLrE0O0IZAHp2ja04kCdZGbgM9s28ZE1XukiGJVZiUMclkwJfK38bDuVVZEu1iytKlR5hcdim784VymXO0p89x8rkXWV07QDUc6HOJI0+7zIOgi7ozlyklbdJwUllNh0qp91APPYOBZzgY4cXx1Oc/zwcGFRdccxWL2BDigkoS42rCkhvxxpMv8YMvf586jWibJu8/lYPgzaxUyeICuvcxWBdNnjdo2b1oeKDAH0C8Z76Y0cbA+MAqo+UJsQ1snjnLVQ98iOt/9hOcn8+05wAdCr0ahe/97p/w7g9eYG15XVPU1gZWPG0zP5KEza3T3PToLTz8m49yfr6JN23lPSxXa3zuX36Vp7/6EuuTA4S27SCa5EC6eVRWL1FKTY0HKrubBmGscDMm6caRJ8tciyMPWpbkETSdO42Bi6++irS8TJjuAo5xNeTsq68xe/8MS6MhbTA8kVq7ZizmpASWXY7KSGkZc0nAOwPogjQR33gW0wVDXyPntvjeH/1bLrvlJo7cdD2TtWVaFpw9f46nX3iZt158Dd+ghRZRtA7TCK8xD1ORlebo9Y8QQyK0SZkBpzUFxqe5QcQ7z3SxYOnYUa596D6WLr0IN6ggwWx3l9HaGpttS44DeCespMSTv/+nvPuDF1hdXqHNIV3pRE5dSC2I3dzZ4KaP3crDf/fjbLW7WjPodCDUMst89ne+yLNff5m1pXVik6u3crV2Li41rUruU5C89QoCrc7TRvbYP3AW7sm+skBq7De/35Y4zwVXHKONESIEIlXb8v5LL+PaFmFc1BG5kEHK01qETHrFndYvWNaqASmSEWYREQ8L11DHQNW0vP6t7/LmD55kMBkjTmgWM6SJ1NQ0i5bYaIAZj3ZBxWjZWVtISKQAbRRCgNgqYA2iFr6IvWkp7zx7TcPBW6/jjl/5GdpRxXQ+1wIXwB9aYxYSuTXSOWF50fLkH/wp7z/7CitLy1aPoOZUBY/iaTkRNrfPcfNP3caDv/UoO2G3RAQTwpJb4nP/9HO8+I2XWV89RFg02ofpMpOCziMrqMrMqXVloTUQRKjUtJv97WVkyuhTI1QODCRpjYhCihE/HrF08UU0i6ZTnbu7bL75Fr6qDC50DQl6jaKJrL5AaNs5bau5Aecc9aAuYEiDhIkYhaYNsNASL1pHqoVqWCEhEme7OO+pzR1s2oYYYimclEGNT1EnnadAjFr2JklNkmsT7SLRZk4UA1JIVl6IczRtYHjkQm779KfY89BO95iMJkgI4IVFaLUXAX228azhyT/8M049+xLLSyvkrqqshyNacJKHcG7ubXDrp+7i/t94mO12J8fCQBzLjPnSb3+Ol77xImsrBwlNSzk4wRVaF2Equ16ESZin1mYeRipSjlerqozZtUg2M98YSEx1Z73gUFQ9OnKYweo6e4sGiYnKD9g7d5rd02cZukorYTr9aRveAZG2aZg1M5YPH2D9oktwlWPv7DabJ09TScV4PNFGiailWRIgLKK2Si8SYQDtPCKVw/tEck2pD8wtV1nyq1rxXNNOGY4cqwcmVN6xuzVj89wU72qqqmImgTLQIhoTOAhJlek8Rm6+/27CZEAznbFcj3j7O09z6pXXqSYjrv3IPQwOH2Q6n7FUDXnhz/+S955+nrWVdcK+RArFQ0oxIU7Y3Nvktk/czYd//WG2mm3M8IIIS4z58v/yOV5+/CXWVg6qaXIOydKesmyKgVqlfMZW4nXYx1X3f5ALrr2a2WxGtU+6zcZ1Y1QpLUiSXUDDCyC0ITBZXYPBkNAsbK+FrTNnCdMZVLXacrrFIMkQNDSLOW51yP0//7NcdudNDJfHKgVNw7k3T/K9z/4VZ378HpPJEikFCNY1ExLRq0PiAoQq4XykdclCydGkKeBt4pn34Ctg0HD3Pddxy51XsnZwiPeB+d6cE6+f4YmvvcjZd+aMJgPmKajWCQkXHEHUGIQQGK5OWL/sEubzKZPxmHe++yzP/9mXWKmGzNoFu2fOcf9v/gqN99SopqzrgQqDRSxzllC1gcYmtvc2uemTd/PBX/soG4sttORG4yYrMuJr//wLvPyNV1hbPaSeg+1r0dWZ+B1/ddYrOwbA6KKLkSNHYDbD5QBBdm9ywwOoXfLJknFWR66NDpqwCSkxWl7RKpcYSTFSpcTe6TMQQ+famJbRmgHVNu2iwa2N+Kn//De58tEPMZ14dtKCKdotdNEdV/Ar/9V/xKV3XsN0MaOqBzjxCgxNMkNMhCCEIMTGERtHaoTUJHPvwHntGvc+EKsZD3/6A3z00x/gwKVDZLxHW+9QH2i4+UMX8hv/4GGOXrNCci2DscfXUFXgfNIWbiCGQD0c4uqaGARpAu+//CpLVUU9qlhZWmZ2aoPdU2epax2hu3ThhSQ8lXhtsM0Z1gS573Jrb4MbH72TD/7qo2zOd9QjMbu96pf5+u9+jZe/+Qrr6xcUUNwdF9NJf4pRXXErJ4sE1bYRnTOQEvO9OfOdGc3eApdtfUr2xZCsJFklXQMhqQxV6FcHpZQYLS0RSernx4QLkenGOY08WZVr5lCnDjQpJebSct+v/QxLV17M+a1NlqoRy7FisnCsjZbZ29tlr2r42H/48wzWx5w/f57t6S47e7tsb2+zubnF5vlNNs6fZ+Psec6fP8/G+fOc2zjP5tY2OztbbO9tsb23w3y2y+bOOe544Cauuetyzu+dZtFMISU8nhQTO7ubjNZm/Nyvf4DlQyB1wg8q1SBVNBc64AiE2ZQ415hHjInRZMh8PiVGWCzm4B2DyZjUBhWeKOC8gr4oRe078w62dze44dE7+cCvP8pWu0PK7mgQlpjwV7/3ZV756xdYWz7Qa/bIlVI5Vd8z+ijNMt3yHIEYAoRAalqkSUiLxgEkBltUruYVVblRkbImuAw9Ih3DEKnHQ1IIWsErCdoFcXdqXp3qnpQrSYMgvmI6n3Lk5qu49I7rOb+7y/rSMsd/8ALPf+FbSIhcc++t3PWp+9mbz1hanfDRv/MJ3n75LQaDgRVIaFOIN4TtfML7pFNOvIabqzpZ8AjqSqjHjuvvvZa9+ZTKecr0rhSokuD8gMVsxqGLD3DHh67k8cd+TDUa0S4E5klz9ylSAbsb55meOs3w2FGm012O3XMHW++fYXp2EyYDrn3oPqpD60zne4hU7Lx/Bu9rO6TCJp9HwQObuxtc/8idfODXf4qtdo+C00VYciO+/q8+z48ef5G1pTWtnjIC516IZPmb4mH1famYMgQkEWzUcSQuWsIiElqoUgnsWBo4+4WSff6eeUgJSaE0FSSSpndTNHUWiSGQmgW5rrDYfjzJwpoR4eIbryHVjrEM2X3nNN/8149RzTWE/J1/93WWDqxx/UdvY2d3i4tvu5LL77k+87k9VGu5goh3UW18TiD5ROUjwyoxqPU9kUgz39U6RvEa2LLmFXV6PQMRJLZcee0RvjN+g3am9s8LtKb9AFKz4N2nnuXGY5dxdrrHcHWVO/7Wp5lvbFItL1EfWmdrNmN5NGbn3dOceuMEo1qHZHvR+UXOwebOFtc+fAf3/PpPsdXOEHEEApUIqwz563/+WX70+IscWDuoMwsw7OA6l93ZvtuUBdvzUMrqcqNOPi6HCPVgwHA4JrlWzw2kp9KL+5cy2OuOQivzZ5KQosbeIZuOUEa/JCsjy7VCAjbP0f7thMnKKglhWNe8c+J94jwxGS+BQGgnvPPaCa574FZSEnb2pqSd3XKekdaRBHWdfIvz0ZJMWlZdVTD0kaZKDOtYbPigsghkSgbAxGSpViaQhIvCymRENXA0e+Zu5tiF6JyBYT3knWefY+2Ky7jorjvY3N1lRsJfsM5chNnuDivjMfXugqce+wpu0SC1CkoUrf3bnm5z7aN384G//TG2wtQENWqQJw3563/5WV59/DnWVw9qAYsuVU19MSHKoOK6QRKpR6cs+zkSGBG8q9h88y0kQBMClfV8aA4tqQ+ciFaUGDO2KACiZEpEc/WxbckDl5IN4JXBGC3DtTn3pkGyoUrAbGcPj2fezDh85GKkFmbTGYO6Zjbb5fAlFxBjom0TflhTDweFSOJRSRdwPmjhiTFA5SOVF4ZVoq4iVaUaIkmkDQvtV0ielkQlCnCDKmY8mpVsm4Zg2aQiFPb8OVU7Es+Ln/0ii609jtxxC240tNCG6HMdf4dnv/JNtt56m0k9IrY2qrYStma7XP/IPdzzK4+wFXZVYYtipJU04vHf+xyvPf4CaysHCMHAtBWtKjgvqTldozNzawWnksf0ZXAoUlLLde04+8ornHrl5RwKzrP0s3Z1IFrlY9c3LlLbksvFTSXQzuZaQoVOqxTnYDxWz8BpGLWcVmGo1eF5/8fHuaW9l8V8zvqlF/LRv/UJnvzSE6T5ghvvvp2rP3gzm7vbVK5m7/gpNt89gx/UVJVHKi20QDJCVxevrj3eK3L3VaKuE9XAjiIaJA4fO0Tw2lDZ0rm7LS2SHCEFhm7A2ydOMps2ODwEVyZ3dmNWhEo8kxj48Ze/ysmnn2H9skvxS0ukpmF6+izn3j6JawKT4YgYWhDBe8f2dJdrPno3d/3Ko2y3O0U4XHKsUvPE73+OVx9/jrXJKrHNZx6qmQJdo4B1EXk1/8EwmrnsETPZEUTP9CGDRYcwrCv9vHOqAcT8UeVtQ655YXYIcm6j6nOViGO+Nys16/mohHppYsyqq4gSLLCkJdnD4Yh3X36D9187zuEbL2dre4ur7r+Ny+64jsV8xmhtid3FFElCPQ089k//mK3j7+EnE0oHmmUSXZVsurnHVR43cFS1UHlHNRTqiWO8UtO6OR//249y1e1XMNvdZFA5grMGWPE0sWVQDZjuep76/uv4NKBtI0G744gh9xkadrCp5EuDMfMz53n31JmSJKqcZ1QNcHVFSA04h68qtqd7XPPgXdzzi4+ytdjtAJ04Vt2EJ/71Z3n1Wy+ytnQAYms4S3HYbD4juoSbDEniSbM5NK0ewuG1ENVhhTAZCHpKci8Xxkxne8RqwWBYMd1pNB0cYy767FRcFx2CXGuoESkNZmAh3OnOLkT1kV0U2giT1VV8CUhkrKDlXCRzf1rhm3/0eX767/8aq5ccYHtvR9OzgxFbixmjqmYSHX/9e/+W7XfOsrp2SAFZbgkT0bmG3iGVaFWRA187vBcdw15B5YQaz6Cq+OFfPc3hSy5k7fAqi9kOIeozRQkM65rKT/jyX36X99/exsuIRdPoCDk7/DlZxM4m0UASQkrU1ZBBibxgmjPPSwTEsb23yzUfvYe7Pv0IW82eqnAB5ypW3JAn/vCL/PjbL7K6sq4NsU4JH2PLNDQcufUarrz9RsaHDpDEMd/Y5uSrb/DWUy/g5zpMoyTQJAN6VftREs5X7Mw3ue6eC/nEr32ElfUlnvveq1T5mJXUW3+yxgnNAoqpFSuetNeI4MUz39oizhekKLRoXny8ukryXitfCjLtMESIWsg5P3mez/1Pv8e9v/gIh2++khmR2ETGvmJx4gyP/8kXePf5H7O0tEw01ZdPEfM22JxKzzdwlY1X8RgwUnUdo9DOIwPn2Tsz40t/8GXuefhujl51AdW4wluu/PzJXb74V0/y2rMn8XHEbNrSLrQlPQY9v7AcEumihqaLS9xzwA2La4Wxlhzv7m1x7cfu5daff5iNxZ7WCYqWp62kEd/+wy/y2jefZX20qsWgFsgOtCwkcuenf4rL7rmVeQw0reZiJgfXuOm6q7j01hv4wR8/Rru1S1UPVFNHyKefJSLiK/am21x/7xH+wf/1V0iDPRZNwyPX3GEgUDJI6/xGTHo1S6WAQkqGQfWBHwyY7ezSbu9QrWgla2gbRivLDJeWSFvbevBULi9LLkNYQoJBVbE4tcnX/vmf8un/9j9FDq9BDIzxfPkP/oLTz7/JgQMHNZdu00ydF/zA4ytrDK21vcrXYvP2MenpQiQhCs08UUnFzqk5X/uTb3Dg8BoHLlylrhw7Gzu8f/ws851IxZj5tGUxjbTzSNMkQojaCVTK5BU/JOlrzJ5pzJkuEtuzba796H3c+KmH2JjuliP1Kqfh3W//8Rf58bee1UrgtlEGcqIZx0XDLT/zKJd9+B7Onj2nbV6DIZJgOp+zvTNl9ejF3P3Ln+KJ3/9zKnJRrNInn1uQ2gh1yyd//QEW9Q6bm5s452nTDpWgwZCuAwVKxWSCfQMS6cqu9Qh4mO/sMj93luHaCtJCahKDpRUmFxxi6/wGvhoQYiCnAHVQA+WoVi9ou/ciAy3lRucqhuMlU5Nepbz2+NpTD6Eaalt4VTv8wFmXsDNwpActpjblsUbENtLsRqQSnB9y7s1tTv9YI5aSPF4qJHqm0znNAppZJMyTppLbaHN78qx/C2xZXMCRXd9YspzeC1vTHa556ENc/6mH2Jhp04bGToSJG/GdP/4irz/xLGujJULbGJBW6Z0vGg5cdRnH7r2bs9tT6nqC251y/KmnaaZTLr7uGsYXHGRrc5f1yy7h2J038+a3n2YyGZMkFK2UHMTYMloaMDm4xPZsiriqHLplbT5O3YkSuLGxK5J7A7I3T48ZrFZ8MWfjnXf0UiEQQksQz9rRywgxoEekJCQ1uGQVrxlVmQ8a53MW87lW7sZErCuWLzhAtBkCeYy9qxzVQKhGFYOxZzCpGK4NcJNEGjTIpIXxgjRY4EcwWKq1i9iq2EIbafcCzXZD2I2kmUdmFXEvMducs3t+xmy7odlpCLOWsAiEeTAAqGtTjyAfPulJeAL0NINu0ebuNlc/cC/XfephtpoFMQkhBEIbWGo93/+Dz/Ljv36SteGYGJrSe5NMCNrYcuTGG2mrAUk8vkk89Zkv8vJjf8WPv/4dvv9Hf87i/TPU1ZD5vOXia65EfCI1WpomMeiftsGnxO7pLV5/5jjDepVp0+iQipCsIshUVzKWycG7/XNxDQiJlUYmVYkVjnNvHefoBxaGJXQg48FLL+GtyhEX2gMnJRhgJUmmWLwI01nD1rkNxnIJKSUaCVx9z6288b3ntUVKgp1fkPC1UNeOeuQZLFfEOnDJVUe45sYrWD+0hJfIzsYGr710gnfePEftB7QEQorQaipZGzujDpJMKsmxjYSIov6gGiO0OkUkJGvINOJkyJzP6dOIqeEcl9id7nDVQ/dy3ScfZms+t/Y47UNYoeapP32Mt777jLp6TaN7L1iRnLXnVZ7xoYMsFpFhNeLUiy+y+ca7rK2skVJke2Obt555ges/+Qiz+YLB6irVsCbszpGq7mnzCEQGseYv/8nnOXTJb3DgxjWmu9vUlcOVJkbMz7We/xxR6v7WnqGoCT1TrTrpcufdkzRnzir/t5H5bMr40AEmhw5pdU6yuLRFHC2KSbI6Q9rEyVfeYJC89s7N51x+5w1c/cDdnNvdphoOqGqPryuqWtvC6yUP48S9n/gQP/2bP8fNH7mVS2+8hMtvvJi7P3I9f/vvPsrDn7gVXy/wA9FSsKTEDYvIYt7STFsWuy2L3UCzF2imgWaqrzfzQGwgLiC1SecURYqGLMkx4+YkApVjp11wxUfv47qf/jibbYPgzcxEVqh49s++wJvfforV0TIhtKQYSCHovODCZKa7e1E9Z/n9KAK+0tEyon+LzXrWIh3d3FjWptepqwGzM4l/8d//a848v8losMp8kY+6NzVQDnkqUKCPbimSqxExm2rhHHF7h/NvvkElQhtaYtsSqpqLr7teUatpkZQ6VzLbk5RgOBzz5lMvMXv/HFVdkRD2YsNDv/EzXPfAbWzOtpm2M9q4oJUFwQdmcc6tD93DjfffxXYzY3Nnl53pnK3pjI3dHabtNvc9eCMf/thNtGEP8TqnL4aoNn2RiItAu0g080iziIR5IC0iqYHUmLawuULqDjtiZlr7k2yfRDx7iwVXPXQf1//0x9mOLeI8FqFlKdU886df4K3vPMPKZLk7CALdT1XbIFHPEoxNYPP0GZzz7E3nHLzqClavvJTN7V22dqZUB9e44p47WUSbsbynGUrnrSwoN9iqPiGmxHg0ZnEq8a/+u3/DqZc2WRodwGklpBUplGCmdMTfxxSigSHDABIjKbZIDLz/8su4+axkoOaLhsPXXcdgfV3LlugWVGLVBj7rumJxfo/nvvJtVoZjQJNKc9/y8N/9eT7293+ZK++/hQtvOsqha46weukhLrv1Oo7dfhNndnZooyMkR5s8IXna5JnHxNnpOe6871qOHDtAa93IMSkDhCYRGoiLQFxE2nkiNEJoEm2jJ3tGywDqrCTs3x0skqTxCJxjd7Hgigfu5dpPfJSdZo6LCmbFeVYZ8NyffYET33uG5fGSjadPJgA5YROLll0sprhJzeqFh1nMFsSQmDvHHT//01z/qUe56tEPc8+v/wr+wkNM5wtG9Ygzrx2nmTaqGVKO2Wa6qevepsRovEy76fmD/8ef8N4L5zUbaJ4rGgjq6C4WwOlAAfuYJKEVM7V3bJ94k9l7JxlcdIRFaGhjgNU1Lrn5Ft781jeZjCdaEEL2LDJg0nLrpaVlXvnWM1xy/VVc9cDtbG1v0pDYjC1H7rieK+65AccC5wLOO3zt2AkRjwaago/4qH2G2GFXMQRGI7j6hkt588XTOBmaGVOTFFv7E7vJXUTKbqB0Udxj49rU1enCyIJndzHjio/cw7U/9SA7c8VCUQRxFSviePbPH+OdJ1/QQZOl5d6ESDp8JQLtYkFbe+76+Z9hcskR9nZ3dYR/GwneceTu2xDnWbQN0+mCydIKuydP8/qTzzAejFXec7S+yK1YQEpH5w3Hy8zPN/zBP/wzPTk0o88uBNAxQo4iq8Sm8l4ZyY4uPO7NePf557ny8BHmrfrt00XLRbfezrsvPE+zs4OvKhvAoOYmp5XBk3CMnOcbf/A5cI6r77uNncU2bWrZ2Ntl4IV6oLl/FyMVjopKp3iRCHid8J0ySydq8SxSYO3gBF+rp5Orm1qgNVsbgoK9wuwZr6YeI6RoBDOQ7HSS595sxpUP3MvVH3uIrdlCewCSpslXpOL5v3iMt596npXlFVKbCW54pOd1ORHaZkFTee755V9kfOwYO9s7VE69q0Fdga+Yz1tSCrjKszJcYu/4SZ7+y8/B3gypnM5aQqzS3OiYetpcdAzvsBrQbrRaFCrlKfNEAshNoj2eIHNKrmvL7yUBX9eceuklLrntDqr1A4aeWwZra1x+9wf50Ve+yJLXWoA8EoactbLbeiekufC1f/FnnHrrXe745P0sXbBKoFEt5a1T2AvJCW0SfKqQFPXwRVuPk4SXhOBJrdc4uJ2NrHY7FrbGwGxMOaMmZSDF3/gRLPeu4HpvtsMVD97PVY88yNZ8YVNn1HVdwvP8Z77EiR88x8pwidhGK9s2d7s0aOjpoYumIQwcH/zVX2Jw7DJ2djapXE27mDMZTdh6400W23usXnwEnGO+t8s7r7/BO88+TzWbM6grPZC677InM+XJoreWV5CktY3iXc8N7HM//54NKPFiKUQvN0tCXVXsbW9x8tlnuOKjD7PVNHjvmc0XXHTrrZx+7UdsHX+L4XBowKk3f8DIkmLAO8eEAS988QneevYlrrnnZo7ecDnLFyxRTQZ4L0QJ1MtjqpUJiwg4r6YAjQC2MREsIudkzNn3tq2/T0Gc4HDWGxCyOUqqzsuJ0KUSyo6GzxbQNN7ubMqVH76fYw99mPPTGZXzVvnlWabihc98kbeffI7lwUSJn5/ShkXm8R/OUYj/0G/8LQbHLuXMxi6V14MrxvWAnR+/wTN/8Rlk0cBkWePgiwWyaBjWNb6urUjUGCyHbMy9LL2LRrioS0FSolI30NCtHQiVmUDMrcimxHILdpO+ytTQ42A44OTzz3HRTTdQX3iEttX4fVMPuOahh3nqz/5UC0fIOXZjttSd5atHycLSYERzaotnPvvXPP9Vx2RlxHh5wGDicXVi6ZIL+Mh/8KuEyYB5q7F+nTOh0t8EqAcjdncCrzz/Fo6admGVxQFCiITiZtE1TYjNSSQRY8ek5XPAdDbl2P33ctmDH2bLRsqmGJGqYikKL37uC7zz1LMsD0ak0JCS5k1UgVozCKK2PbakpRGP/PovcuCKo5w8t42TmtC2jAcD9t46zjOf+UvqRUs1GBIX1kHsHG44IqaokdasuMnhqLSflhnKGWOYf48dURMQmw2y7+Ch2Nn8cnVDrRo6zp0I+pqzNOVb3/0+gwRUehLmPMLy0cu55MZbaFqteskJpnJh6WbwkxKp0eEPy6MxS1JTTSNpa07anDFYJGbvvsePvvFtlmQEacAiJNogNK3QtI5Ixaha5ltfeoqz725DKyzmLW3TatlazO1gieyZJqunL+PepTNzmInYm+5xxX0f4ooHH2R30eCTdlcTEktN4MU//yzvfOdJllxNbBakFFW7pZbSEqfxbRYhEEc1D/3Wr3LhNZcz3dmh9hUhBiZ1zd6bx3n6330GN1vgDdTmRp4UovYCxmTVWV0FUKFfTsCVV7PQxoL7qnzUSccxNrQhZdcQK+fO/G97kwFMnlitrMVoOOLcOyeZbm1TXXAhKQSNR6dEiIGUzAJnD6MUMxrhaVXrCLhoo1xshp6m94SwSAxHFe8+9Qx15bn+wfvxy2OExMBHhlXEz3b5xpe+yYvffYkq1Ex35zSzSNtEYhs0Y1YCO4mYdBqq5ap6JddlD9mbzbj8vnu57MEH2F4sdLxNiIiD5RR56bOPcfKZF5hMJsSw6EVRbXfFl4bXkCJh5Hnw136Jw5dfynTzHLVhomE9YHryHZ7+zGfx8xZf1+R6v0zMPBJHaZBM7UfEtLHWK3Sj9MvZAR1ygwSVpGzfbNJn6jrKsNSiEipvRuawHGzI0gIintC2rB49zGh1nVnTgDlMzc4uG2+/o8OcsjrK95NsCjD1mJkhR+8i0Slab5uIX7Qsdj3DZc+JHzzF+ffe5pLrr2Xl4AEqB7sb53j75Vc5f+I0PjjmOwvaaaCdBquGDcRWnyVJFgihOxNJiYSkYhr2ZjMuv/9DXP7gA2wvGqvGSThJLAfhxc8/xnvPvcDSeEJMAWfBFzFs0mUJ9ZkbL9z1Cz/PBVdexnzzPBVCS8RVA2RzxvNf/Aoyb7SzOsaC4Pf/FG418khhWDGadEq289ukCDFUKUUbx26Et7ZoREoOviCgDGDo7Iq+pe878TRELr3iKtxgALMZCRgMhmydfJvd8+cZVzo5jMxgpF5wJWXNq/cIkeAFFwUJ6rO3NopWwVRguDRg78QZXn7ntPU6C7GxKdutY7EXaGctzSzQzjXok9pITKJJHkP+nbQkurHjahL2moYrPvIRLrv/PrabBYIOp3ICK0l4+bEv8N5zLzAZja31S6wngqLN8vY551k0LevXX8PqlVewt7PFiKhVx+gJJxunTzA7v8V4NNaaCueKihdE1b51nuYytaL5+9i6V+TRhYSM8sYOVR5CTAolKrX/dO/ehcoR5WZXxL5rrk9IDW48ZPXYlcwXuV3ZUYXImR+9io95Jl6Ossl+aS+ASzrmslM1UqumyOFpyuciMTT4gdYCOG+1hwFCEwjzqOHcRUuzCIQGNQEhEXJCMtvIYt0MOVu93TQmrv3owxz5wD3szOf2us7nXwFeeuwLnHzueZZGk8LMvpi2TnaywMYYiK2ah0XTUqdAlKgwQgLBUSao5IkteYaCdIvU/0Rz7/ZV89hbVrJWtGvmwpzptQtpJNB1yBGSdgeJoUXJ0YCemjGuyyheTV1i0TSsX3Ypo9U1dhdaJu4rx3TjPOeOv03tqzJFAzq/Xc/d1fP1cuYwazyhJ6VRaFttqGiTdiOFJuArh/PWy5D08ylGUhOITbb7hvxz0Cdrz0KeUNSsc555WJCGY25+5BEO3nwz2/MZ3qnar2rPMomXHvsS773wCpPJCiGq2nf9zbb1kImUtXKyeYghEFMgOKuFwKmWsO86I0kscxP2o3vzUwvT6jWsFR4pz1YOniwb3tG2ivZmip1r0B30nHsEe+fyiJBsAli+OQk9yiW2HDh2JSG10CaS10neZ15/jcX2NuOBjqLNCDRrkny3woQplXHoSOwxgbOzGDSUK8HROrQryAWTNkPZdvBSCMmKO1NXhlCykoYxMkPboKrpdMH4kou48WMfZ3j0KDvTmR1klagqx1JIvPTFL3PqhVdYmiyRQmsnplNGzUIWECGHeen4QF3uGOzoG90DSRHaYHSQEpbO6ZiSg5AczJJO0dhXcju7lK3MIDBzTc9WgEYCyYcnJD1ZunPuOgwrCTC1tM9EJK0NCG1gMFli7aJLmM0W6hYmh+y2nHnlJXxsNJBgrlA+4CWGlrZt1Y0Vh4+RwbDuilDRXv88QTuY6cjYRZyd+9sB7mLKUrScf9BnyDF/3ZheBZJ9tZnPiQIX33onV3z4w4SlZfamUxyeSKKuagaLOS98/guce/VVlkZDdSklkodp5PL9lFzuse6ta7/W0VR9srXpc8RKU8T5RJYoORvZB4BdjKbkcTIuzw5/3+6Qp4NkDkIlQUSPjKFfQKiCZhyp7yUjjv3Sk1mLPtmpFQcuuYxqaZlZ2yDoaLPpyXfYPnmCgRNS0FLnEBvaVjFHNRqzesXlHLrySurxhJMvPc/mW8fxItR1XVwdXb+FcKMQxLCa2FpRLJIwybFd0e/mw6t6G2N/C9CGlqZtmBw+zJX33cfq1dcxjZCmM1yl7Vqj4QjZ2eb5xx5j+/hxJsMBITRFa6qUWkAr2SwlwZo6Uol5uKwxyUwZCEkriEMSWq+nmdiUyR5e69n5/vol11nmeI30Pi8laJfnOmSMm2JkFhvFAPlqBQB1ot/7EUoZWDEH2aWLJOc5dOwqGvFAq8eskDj15o9hMSPVQx3TBlSTMQcuuYyVy4+xesllDA8eIFQVJOHaY1exdeI4J599hu333sPFQF2Zi4pYIko1FiG7NKmDvtp7ZXY3i57qHHVxc6N8YNE2pBgZr69z6a23cfimmwnjCbsLreVHIDSRyXjA4t3jvPiFL9OcO8N4ONAgTJ+L8uaKCU3qaa9kJfFmNq0Pi5R05GCg08ApqAeTYujQfanWEjPBvVqCSC+p1lP59ruQoULpFiDFyLRdcNUjD9mEEJP+PAEEu1mf01RfYVOz8g1UNYeQGKwdYvXIUeYWrRJJsLPNqVdeJjYtcbTE6pGjrF9+JStHL2W4vk6sB7QhMo0BaSKIZ+EcS9fcwPVXXM3mW2/w/ksvsX3yXZjP8ETNjv1ErMD+3z1sdpvJRemKJ1JsCaFRCasrli85yoXXXcf6VVfjlpaZtpFkM3RjiFSVZ+IcZ576Ia9/83GYL6iHA+3VM1Cm9MlZvd6+kfFILK9r1jKpq5YlN0arDUjWbq4FqClFYjRUJJlxu1b7VICUaZjMfD2BzWY0pgwJVWNPZzOu/uTHOfbIg1QZEGWiJVMj6g4abMxgTYwDDYCAgFPX6tDlx2B5lXauffeV92y8f4rhyjqX33YHS0cvp14/QPI1TYzspQiLYOc+u2xMdIHzGc5VLF19A1dfeQ3zU++z+cYbbL7zFntnTxOnexBbPKLFouJVYnEE8WXjNfevU0WkcshgxNLhddaOHmX92JWMD19I8jWztiU1rVYoJ22UGQ8GyNYmP/72E7z/4ksMK3U1Ywh6SlkCa9LujHtGLSlH6FRwTBkbOOuKbQS0FMzl8HqunewUS8nhZDqYFlNHo0P6hWbQu1/HimVvF3Ou/NjHOPrgRzg/mxkILPKTOVkfKNkxsH2ECfuDJgK4uuaCy69ggamjpIOUBhce5tqf/gWk9rQBpilBq5M1ySdkOaGqKryvCKBDoJLmvGezGUmgvuAwFx2+mAtntxM2zjE9d5qd8+dYbG0zn01pFw0xtCYFDpzgfMVgOGS4tES9usrygQOM1w9Rra3DcEBIkVmjR9Br1kwHLQ0GFVWz4PSzz3Diye/TbmwyHtaGMLJbmm3z38zvZ5JI3p2+RpBkhdhigM1Zw42110cgSJG5LpTfXVdJE61nM5/H3uVRshkvvn8hPUzbxJUf/xSXfPg+NmczfCXaFwBWsZ/23yivIGRc0ClZVUviCU3L6MKLGR++mGnT2Ph3dOTqyDGLgdSkLhtm4dWqqhnUHgmR6alTvPfGG4xWV7nw+hsI9YB5syClFhd1lvGeFav69UNMLryYFefomvaS+Xc2/F+0FAvnSZWeyhWTqthZCKTZXGMMks8hFIaDmuGiZfP11zjx1FNsv3OC2guD0UjzBCkrX0HP9O2VUxa5y0Swv0vWNBPVEYmW+bSQXUxm/xMpOjvBRPfdpX5GLxM/+/w2Pa1gvty/mWs1jJYC4jyzxYLLP/wQlz74MOen25pcSimbgLz4Ll5cyrczahVskHRPMxCZNwsuvvQoDAakxUK/LaLhS4R8Nm4UPe2j9h4XIotzZzn7zgnOHH+LnfdPERczcMKZl57nkltvZ+nyy2AwoAlBZ+qlZEUgQdO64rQaNvvvVa0dw7n/P0c2F43WPOaoUsk9aCPJ2E4k33nzR7z+/LOcP36cKkZGg4F6RlGrdToxNmq47l4lztMDYn3N0PtyPher23Nz27LmdeZFdLWCndeQXUz10CyMjmpdlzLutQhg1lmiHdr10gpH77yL7dAi3tnEX8kmILOZlBm4+krPvtm0zIRGsVSVtYj3rF58MYtWBzE7UcQe7ea+GjDwFS4Fmq1NNk4c5/ybb7Bz+n2a6ZRahEFVQe0hRabvHueVd48zueBCLrzmWlYvP8ZkbY1YD1igTJiHIRC7+gVctL7B0Nu8vLNZdh3eOwbe4doFszOnOXPiBGd+/Crb751EYmI8qHFVpU0gkoo6LUQrzNBdO0/tzuNXU+o7yrk9HnUTyUEa9e+10VSDQDphPtqUVt+RZh/TGBP0cUI2x2Zagr2W83/YvrVtW/SUWP9HVaJ/plKU1p090fuqNvC5QDKZKxYC1XBIPRrTNI0+pPe4qqKuKnzb0Oxss3HyJOePv8H2eycJuzsIChLHtTeg1thZeYm68tQpMT/1Hm+9/w7VkxNWLrqI5aPHWLroEpbW12FpiVjpwUq53aDgGNkPaiWBSwHfBsJ0h9nWBuffP8nOO2+zfeo0YTrDOZ1Uom3WFjtAyE0yedaJVdsVRVAYIZsA22+RrjtQekTI8Yp+XUBqWjtZLNkArtBza13ROKU4O4d1hX2yS7b7MbvrptOjNs22u7uceullLjv6KJtTnVFUVY6qM13mZtjNJAddcJTDosvD6kKcOOazGVtvv82Ft9zOIiV8SrTnz7Hx/nucO/4me6dO0+zuAoHaO2rvC8Pl84kllcR8qTmuq5paKmLbsnniBBvHTyCDIcPlNeoD6ywdOEi9vEw9WWIwGOLrylwrreWPTctiNqXZ3WGxtcnexgbN1gbznW1iu8CJ1/UMKkLqlXznwyayuSORxBWDmLLrBZTysUwHq0OU1FPtGDiUHl2triHPYY5h/9GwWvSRNOvZo3BXvdTdtlAkK2tJdnRM52mklBj6iuPf+TaD5QmHb76V6B3x3IbmAorblBJdkKHPu/patHJmlxchQp0cb373CfbOnaMajdg+fYads2eIs6n6C95TVyB4BTxJx5ZFZ25mCuaz54dRDs6g1DmhrjyCFlEsts4zP3+WnfSKqnxf48yjEEPGGmNHy89iW7Jz4oTKe2Q40vukmC0beRpaJGtDyyymRG7zLjaZ2MXaoXhJXeSm0L/ggZQSQVUkpRgmaWpaM3Tmgveqkztk3zGfZA6w22Xi5w8mUjl5LWcDQcO+g8Wc1z73GO8++UOGkwk7p05pQYhYl6uyUOwR3ghi5wZSqodyEBhcVeFS4v3nnyalhHcOX9VU3gIlKdKNHM1hybxBXTIpQVerlq+dOTh2Jqn2QnIOoSJno/Np4LloUUwdSy2IDIq05VSo3iJ21EO0LQuVOq0BtYqbshk2Tpdor0kJvmR8mT+X+gagX/FUikKyzQ6kNtCKqv1k42h0u3KKvKdkCspUxioeQBbWjuu6eku0IDTv70iE5sRbLFLC1bVVBKViaig5elIpi9Lyr3xz9V0tJmspAkc9GBu1rIsm2iaTc/uW/49ZkyQ6FtDZeYaU9um4bOdKajNCPj07f7Rnt8hmLKPDlE8gsw3I9zUrb9KSVb1gmdn8dXt+0yBZT5nWcPRr8cSSQnm/euu2BIvIPhQBSXMBjtaeyems5lTehj4D2aqFrlIp2SZlpiwCkJ9f9LlUyPXpnWnUJFAhObTbbQq2zE490uloA1rSIQ8g16CR0VdZcAEwdoH+WyKZkOVDFkjqUI7Ozktl40pbWU5w5I3uhYf798mBlLx5hbK93HrqSmgobmLOEoqdZZo31NaS56fpFZyatt4aRLr7lmfLBC12Xs1VsM/rtFU7RJs8Ew5wvuyR0L2VHz5HlXOldsCVrGCmlKZHuoRQ1g5VxzG9BAPF8YEc9Uu9OUFJpV5r5vSCLg8vzAApP2xPhWYOLK8ktad9IhXik1VcKnUMPZJ1nynfK/+x+xQFSKmGKAESilaw85MKoTIG0Nl51qpd7pWZLpUvuazd7BHVChmRbdFSmlEyj2V1Gwl2fqCIttll8E1huo7QJbqXemuBzkSmLMLdHmVzq0vqQtX6eesL6AxdKhKr5cyuuH0kYwrpSooy1/Y3fd/P3xhh2r3f2cZU3Ov9wZT9GqNfjFrUXqF8jn79zR+1ozmTqOq4ZwC0pHqfDZee2s7/7t7X391+VzkTW9WJ/pWEMnK+B6yTzxdSs6rzA4NCmKhtb7neIZudFCN5BH63kL6Q9va1WyRZoyVUS7hkGDMHiFKi0hMnFehpNVssnJZ6V8x2HHKUK9cYeaTUV/eInBLdUSh94md12P37JwNt/AQpi7T2dIDse1LXU+OmNfehJ4CgqhS6BEs/h16+acwkuU0u9ZgjP0/svIQskPufrsMn9mIODokdbYdk6UyQQpGAXEQK6PF1mXeSMkHWHFmA+unf/k+W/JwVzcINkPsbRYQqti1+MARniQknphGiRrGyvcJcxMxOJN1UlNt7JQf2sPtlJt89u0Td6/ITD7GfWbr3euq+99+fZCzIc/R710w5OJrVaw4XUzRIT6FqnCXlXuYcucsxvVwzkYpa1VXkDKpeV/bvOd2O2LObyUxRD5hU+2ERwUzYZA54QffZPPITe5b2vZ7T06l/PwPfZcdMg1SL6R7j1XWkyke02I1E5/7p2nsbZ2pFioQUUhWC9kSm95MDTR0j7H8QU/l5M8mYg977/b+733sYkn0Nrv++zxVT1QHZTPC+kVHFIKZFk2HbDE7zJvbvYY5xVBCbmzFzoUfua+l1o5BHuuY6DAldmr0Yzn2PbSss95WemGfG6/YnxyaywGTsk82iAG7n3GmW11cYHzxkhQ56LbFyb51DqiVKEgMu6aSv7O6ZwaP4XlljJIrm6Pyy/Me0RspfTYVoyYIi5XHLe/9+VdedcN5tTMwTPDL67v2vrMFwQUoK8sTG2pcuWmOYHL4lv74P1PbXZcyfsUlvT5xpy5Jqky6nT9TaxpTT2YC3wViSC0N7+5TPACDm0nqNO8RQHGXdRR2FTsFM2MS0vPqkWsbNz58jzve4/KYbiWEB6LFZEq2Lsg2adElKdK1mTWViZskmlr2NkFr7bLQNSQWBluojOl8+71f257NvX8KxMUtibyPs/dQL7uS0qpSNyao09L5jgpPvb1opJa3o9Skzgx5HnytxlHDGWPlvsrnsfkSE5F0RXZdTeJj+FCnehSSBNpDaxgZWtAounSdJVdLVheEyAa2oJA+CKPArs2TKLBx7AmkMW/ZP961yoeXMm69x5PrbOP3G5Zz90SsMBiPTyH3V0hVEpPxakdq+VGT3qyuSyJ/IajZjjIKOEp2dMxu73zRgzBILROgMRi6PVubpY4b8CB2uMOAUUqFbzusniUVjaXDIFROQTyXVmQl0mteMlN66N3E1iFmKXJ3aaQYdmBWLEISoVdHO6yCIPJiaZP0AaH6j72EVN9SmlRbPJnVU6CKssTCjvl8qZoFI5QlMT53kzGSZGz/8IV6KDWdffQ2pKnxV92LiUrpmXQkJiw1tzlyHNSFm6eoR1qR6v7yYWpaOoJlx9FJd4KJTMdIjaOcXZDXXh4Yx5RiCPUNhxd5Ome2O9owl6tcDXITsSirD59Hr++B/hOwV5EET/QOckghOnJ1TnLQppG2sU7mxOYIJb0yQTU3Xo5GLWfP6elPBs4uYHyt/N//XGFmyBtILIwmq0DR48Wy8/gqhWXDzgw9w6tLLOPHSi+yeO68mgO5LlPHjdHcpLlevajgJJZ3ZD/OWnZce12Rx7MCm/ruzvYXuRWuk7l4dB9GpB30t9Ait6pue1sn3TiZx/TX23iPpc+c1gZmBHgboJYJ6FyeHzE06VIgWM5rZQkvZmsZiKY7YBmLTaAv77g7Rue75e5fs1t+ndH9ve3tY9rr/aKW4jSpZUWKFZ+utV1nsbnHhsWu48MrL2dvcpp3N80BPXbyd+57Dj/19ylHCzKn71X9eeyrryV+WQrRM9HzRLkhTwh5ZpdoF89CKfKXMfAn0NM2YJTFviqlzRCMjRdJ7EUIjlum2LtMntnmpey9LWUKs5q9PFNeZFjPUSRIpRPzaKqFdEJuGJmhdYmhbwmLG5IKLuOlTn0TwWlFVHtAV+u+zbBnb9PWb9XFGsUbZ3rt93q9SyDYUhs4Tzp7i7c2zjNYOMlk/SD2e4Osh4vNifOfCWSLIZVvTbRkZZe9TFvtUVEcsyVqkvNw9YfdIsj9oYxHKrO4cvffyNyT799170mcAEbrzdbJhz+ZCT9lI+Th3sp/fLdOZeYsWTUSsP7/3zF1dgT1X0MxGiIHFmff0tFE7ZZSUCJtn8FXFytHDqtrFlQYYcgBJOqEpWRLTiknU3HS5lZ5Xlr+TLPiXUm4PtynbEvC+wiGEzXPsbG+SXKVVPk7RcRSnvyMkJzoGNa8t+/qivydXQimQS5lNkpw4y7VnaVbXKKNezXhpLaG6pq7M6ilgLW/sT1iT8jsdY5VeuqJ6hJyhzAzTSa95D10KIac37Z72XDHZcS10mjeni/P37Q3tpNYqqo5hdaJdNGFxQNw4y875s1Y6ZhhLdJ/JrynQUK/EUtb9tZOF1EB8yq8rR3SHSApUKQaic5oGlaQqy4FzTit5HWglm+8ePkkBexobUVWriFMrYpLLqNj8XYIpe12YpNALKWfBD2SV6xGIVpFs9kpfy0pMHzoW7yEXmKRCd3UtNXgViQreTAo0xt5jIovUSG98CkrPQtC+lTcOMPpmxsqejbmh+Xti+yaiFCeVWsAU7IxhW7tIonb5uNiEsxGwed3a45l7DdCwdVE65aFNq9k+iDGrMU+KuQ5DqLBkTnQJiR5BJ3xL0h4+l9TvjeaCORH1kS3Tpxzpsk7sFudzgamVWGVCiiZBchROCWWb47DYt6ORzCCds9mFl402PSxZOFz6Uo6FtvX7pe6F/bihZA4LsDQsYEyViz6z2emOwjUQmFO89GINtvnEqBPLEuRKXrsBpK6VWyyjGInmvjs9Yk+awnbivLYNZMhk/eNKbN9pObH9MO+gHydw0s1mEhEqGwikqtd693VmHohPOpgIh4gH1+WanSS0Vs4hdlbvPgNpDQ7RJnqUTS0quTiYnQlJWKRLmSsfYmlMr4onFaErEin2JzNafqZMbGdmKR/hIrYJGte3QrDQMWE/BpEI+wiaUtBIo9AlblLqGKawdiqmaN+ZTNkWZ8KUAk7pGFms4iALRn7KkBN11p7fw2+5QzlmhrR/5XlXmfWzttF7RUsHS9T5CC5A8nb+X0uKdiNn/WumtnBRFbpAJJAHP0ab/pWPNU2GXlQIO2LqWqQY7UgqsQX1bSXDruJ9ZN7JdLIoZ1da1uOI/F5mhFh86Z7WIH/PiGmb12XfOrHJBC2ahEg+LaQUi0SV4mjJrlJpVZ7brpL0CqVuJiWbsmfaki59nbN+ytz5C3ZauDiSmVUFdG3BZbEXzg65SCUzCoBkc5yo9IhYV6ZR4LBctwMJGowxzkymNvQwIg2HZu5DUPuWOvuV4+rBdHuxU31VbpQJok0TMe0PLvWRd7IwaSzxAqA3vGI/Y3W6oftnzgh0ryfa3rc7ySd/Mp+fgJ16XpafMws9zNBT8RmZd3eDZDUA4nJKyvY0YoJjo/p7z5KJlvceguYAstnFQKEh+2RuL/Z5rS10xnSSgQO50ruSaCFJl7q4tVhaU3SSpstSYosvXCSeAqic6GlXhkyjSY12COkQBUfW0aiaE/bteSFryATo6JL9/RRtGEPKyr01TVRQRY+E3ff1tl21USGTqZZ9wT1zH1Vd69Fy0UiZ+yfKKD1slk8O9aLfz5oh4859jBCs/6BwthVolCBaJOP66Lpqou7UU0yg1OzmoR3ZYiRjinz8VO6KKmcIGM2EXBEEkAJRPCLBgjxZnaNc5bSQoWtDFvRMQLUpYoY59bBAFJCoJ9NkXylnmCl1a/kFocsI5sy8xp2ifUntV5EbEGhTi5h/nG2sPqxdqa/VhFIOpUEbfTZIVtyaK3Hyirr0d8zGNOXDGDJDZJUuRUuC2vyyV7nHwgickzVZunMuoYTXEVJqiE73rzCrhLJXWYVn5kUy/nCas/C6xzk8vU8zlpNFk80HsGcWZ61W0YwroiXYuSwsy7VxlEZ7u+kbrqilzt5HMyWZvB0H5gamzk528KlnH0OXok0mHfo8QsobknLZaFYMZodt02OggC+9hlOmwEyMCWHmHxv1RBI94ygJECzGQVuSVVnLdL8nCx2kcrEe7jXg2UtSmdD0sg4q0dYUIiF1UEQ6UywWDY05X5VsP2wXRMRGoedEVxYMBYYiHmdapyp9bQDBludsszIiLtk7U7FlNouAtGQ7FF1n5zXJpkAoiFOFZhunTER+Mt2a1HkSXVlIf5xsF87MTJTr7nJJdTK1WIZbZobImjWLm2mmXD0TE1p+Zdo1n6au2iaaxND76SKUmYVzJG/fGvPz23vFD0+xaCLyNhiBXC4gTUZo41fILnhmONnHfPl09hzt033rXOkSAjGNpdQMNiXMLtjRw7g+6lRtZaSs2u3ryReckCN9peLAWsSzHyRWXpbjBck8iizZHaWy/cobkjdRyu1Tynlw5XebxoOkPJK2k7i8NQWJJ9swI3g3BCOR2lx4qaYt2WbpYdORrgwum5HYMWeC0vCCBlo6c5PMTqsfm5yaMYmuww0592VTzjvy2hZktzjQeUS915XAra1DuoIoMw0pddtZ0kC2yZWYX+WgTJ8sSdUUiAUYqimIKZG8HV0epdSoR7rj44UErXSuSwKs+0U52ti6xFBzsiYzjbAP8BRdUArTyaVf2VpF23jJ3C8d+k/kEq1O2FJLtx7pnjebnz4OUVaLZX2xFKvlaIK9JZSgkbZ5q1vobPJaUqFUZJ5aTREn0fhLZnIgD4jaF9PO1T396GV5vj6I1Q2RHiPkzxa+6CkfiwOoetL5CgLe+t5Ttrtlr3RbougcP4uT5mxbtkVSKnnsepI1bywPk3WJSnwqGyi20mjAKs/H0eeKdECr17yJDXm2UbbZXZMkvZkGmfjdRqtkmGzs0zqZ6bqfRJfUURbocEYxMS4/pyVlIiSJZeNJfbMTS+Km3/pWtGbqNEQe5FkALQYCpUDRwgT7upW6pZkGFYtddM9YZcpG0PQpQKsb2Z0yYVstdDc0HSkpoWikI0BBqOU3O0Yl2yKiqdaU19FxdG/FsVAplocoXhBJ/WrpmAGbtZe5Pgdl9IXsiGVydrfLalIklfIz8mb2MEj3TBDslNC+uUpBzVXKO997MLXXhnPy4OaUGbj7vXiC5GknFNEN9ow5Fy9ZWsyjSlGNrar4XoIoM52kbt/MLFprWK+4IWnfWGdLk9arCTjLMpUq1pSRaSzmQKLJtSu62VSqlVWbSYdYsoF9wetSvln5doQKKR+t6va7eeXTFIK7HJEjW5XsXiVyW1n5Ea3yyXbfBE2vL5l58rI6A9SVLStn5uaU/XDVUHmeUoJpd6ydLGEHTOUH0Wv1R7+JMVJpf4vlkFnDMFLWmmwPfVmCaUPJyxVjbv1gtVi0RUWrxLcGVqTcuPsrx52zLOVeesgdxF3oszubJ2+yT14n/WRVT2aATlvYkxbFRpbiXPZkn841+DmGXo5NF9GKZsmqkiKROWzcsRQ/8XufOXrYpMwBcNlumKnL1+qePdfNdK3kHdMY5cm6KLuIKTOy7Nc4na3WndHxMnk/JKvCwnJ0/1TsJmhfh808sO3MOkMZ4MCxY3YjKdWqenGdAehEuUxHtOfPqfSLx8K/YutxXSBIjXCJZePUxcnHv4OFfEWZJ/fnK9Ere13BIIYD9Eh4laicK+/k0Wx7lkrJV0slEpac62LwtkbBWQha38hrSvKT0tXtSTGEWaxw5R6CA5eZSJs6nXPGGJpZTSRD/p209+FtvmcOQnU+qImAzbtVBtTR92L5h6IF7b186ot9sVxKbARONVlZ1QfP8/aM1cQboe3h9C3bFNHIYPbixHmjlz2g081xuWZAck2AI7oc6xc7xMsrUi7YQa/jnJTrdKpTtDgl+9NlDZkA0kmOiE4KI7ufCT3x3FlhTV684DOIdV6jls7MmVgWNIuXs3gG5s551VTOKncwptHaDd0LcbZXdq+c5yimQcXUSJRKQEqyZk12eGXGBVmUQ6D0TJRgnmU1k5ncqMzijJFKOX5QryalxP8PyyMkqBwLXRIAAAAASUVORK5CYII=" alt="AgentKit logo" style="border-radius:8px;vertical-align:middle"><span class=gt>AgentKit</span> <span id=h class=pill>checking...</span></h1>
|
|
37
|
+
<p class=sub>Production <b>MCP server</b> exposing your business KPIs as agent tools (bearer-auth + rate-limited SSE).</p>
|
|
38
|
+
<div class=card><b>Connect an MCP client</b> (Claude Desktop, <code>mcp</code> CLI, or any agent) to the SSE endpoint:
|
|
39
|
+
<pre>URL: <this-host>/sse
|
|
40
|
+
Header: Authorization: Bearer <MCP_AUTH_TOKEN></pre>
|
|
41
|
+
A browser can't speak MCP - point your agent at the URL above.</div>
|
|
42
|
+
<div class=card><b>Tools available</b><div class=tools>
|
|
43
|
+
<div class=tool><b>query_kpis</b><br>filter KPIs by domain</div>
|
|
44
|
+
<div class=tool><b>get_company_health</b><br>overall health index</div>
|
|
45
|
+
<div class=tool><b>detect_kpi_anomalies</b><br>flag outliers</div>
|
|
46
|
+
<div class=tool><b>forecast_metric</b><br>project a metric forward</div>
|
|
47
|
+
<div class=tool><b>list_available_metrics</b><br>metric catalog</div>
|
|
48
|
+
<div class=tool><b>get_executive_summary</b><br>board-ready summary</div>
|
|
49
|
+
<div class=tool><b>monthly_briefing</b><br>composed monthly brief</div>
|
|
50
|
+
<div class=tool><b>finance / growth / ops /<br>people / esg / itops_latest</b><br>latest per domain</div>
|
|
51
|
+
</div></div>
|
|
52
|
+
<p class=sub>Health: <a href=/health>/health</a></p></div>
|
|
53
|
+
<script>fetch('/health').then(r=>r.json()).then(j=>{var e=document.getElementById('h');e.textContent=j.status||'ok';e.className='pill ok'}).catch(()=>{document.getElementById('h').textContent='offline'})</script>
|
|
54
|
+
</body></html>"""
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class BearerAuthRateLimit:
|
|
58
|
+
def __init__(self, app, token: str | None = None, rate: int = 120, window: int = 60):
|
|
59
|
+
self.app = app
|
|
60
|
+
self.token = token if token is not None else os.getenv("MCP_AUTH_TOKEN")
|
|
61
|
+
self.rate = int(os.getenv("MCP_RATE_LIMIT", rate))
|
|
62
|
+
self.window = int(os.getenv("MCP_RATE_WINDOW", window))
|
|
63
|
+
self._hits: Dict[str, Deque[float]] = defaultdict(deque)
|
|
64
|
+
|
|
65
|
+
async def __call__(self, scope, receive, send):
|
|
66
|
+
if scope.get("type") != "http":
|
|
67
|
+
return await self.app(scope, receive, send)
|
|
68
|
+
|
|
69
|
+
# Liveness probe — answer /health directly (before auth) so MCP/SSE servers are
|
|
70
|
+
# health-checkable by Docker/orchestrators even though MCP itself serves /sse.
|
|
71
|
+
if scope.get("path") == "/health":
|
|
72
|
+
body = b'{"status":"ok","service":"agentkit"}'
|
|
73
|
+
await send({"type": "http.response.start", "status": 200,
|
|
74
|
+
"headers": [(b"content-type", b"application/json"),
|
|
75
|
+
(b"content-length", str(len(body)).encode())]})
|
|
76
|
+
await send({"type": "http.response.body", "body": body})
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
# Browser landing/demo page — served before auth (a browser can't speak MCP).
|
|
80
|
+
if scope.get("path") in ("/", "/demo", "/demo/"):
|
|
81
|
+
await send({"type": "http.response.start", "status": 200,
|
|
82
|
+
"headers": [(b"content-type", b"text/html; charset=utf-8"),
|
|
83
|
+
(b"content-length", str(len(_DEMO_HTML)).encode())]})
|
|
84
|
+
await send({"type": "http.response.body", "body": _DEMO_HTML})
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
headers = {k.lower(): v for k, v in (scope.get("headers") or [])}
|
|
88
|
+
|
|
89
|
+
# 1) auth
|
|
90
|
+
if self.token:
|
|
91
|
+
auth = headers.get(b"authorization", b"").decode()
|
|
92
|
+
if auth != f"Bearer {self.token}":
|
|
93
|
+
return await self._deny(send, 401, "unauthorized")
|
|
94
|
+
|
|
95
|
+
# 2) rate limit per client IP (sliding window)
|
|
96
|
+
ip = (scope.get("client") or ("unknown",))[0]
|
|
97
|
+
now = time.monotonic()
|
|
98
|
+
q = self._hits[ip]
|
|
99
|
+
while q and now - q[0] > self.window:
|
|
100
|
+
q.popleft()
|
|
101
|
+
if len(q) >= self.rate:
|
|
102
|
+
return await self._deny(send, 429, "rate limit exceeded")
|
|
103
|
+
q.append(now)
|
|
104
|
+
|
|
105
|
+
return await self.app(scope, receive, send)
|
|
106
|
+
|
|
107
|
+
@staticmethod
|
|
108
|
+
async def _deny(send, code: int, msg: str):
|
|
109
|
+
body = msg.encode()
|
|
110
|
+
await send({"type": "http.response.start", "status": code,
|
|
111
|
+
"headers": [(b"content-type", b"text/plain"),
|
|
112
|
+
(b"content-length", str(len(body)).encode())]})
|
|
113
|
+
await send({"type": "http.response.body", "body": body})
|
mcp_server.py
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AgentKit MCP Server — Business Intelligence tools for Claude/Cursor agents.
|
|
3
|
+
|
|
4
|
+
Exposes 6 tools, 6 resources, 1 prompt template.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
python mcp_server.py
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import os
|
|
13
|
+
from typing import Any, Dict, List, Optional
|
|
14
|
+
|
|
15
|
+
from core.config import settings
|
|
16
|
+
from core.logger import get_logger
|
|
17
|
+
|
|
18
|
+
log = get_logger(__name__)
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
from fastmcp import FastMCP
|
|
22
|
+
_FASTMCP = True
|
|
23
|
+
except ImportError:
|
|
24
|
+
_FASTMCP = False
|
|
25
|
+
log.warning("fastmcp not installed — MCP server not available")
|
|
26
|
+
|
|
27
|
+
# Optional imports — graceful degradation if DB not available
|
|
28
|
+
try:
|
|
29
|
+
from services.pg_store import (
|
|
30
|
+
get_kpi_metrics,
|
|
31
|
+
get_available_metrics,
|
|
32
|
+
get_available_categories,
|
|
33
|
+
get_available_periods,
|
|
34
|
+
)
|
|
35
|
+
_PG = True
|
|
36
|
+
except Exception as e:
|
|
37
|
+
log.warning("pg_store import failed (%s) — running in stub mode", e)
|
|
38
|
+
_PG = False
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
from services.insights import compute_health_index, detect_anomalies
|
|
42
|
+
_INSIGHTS = True
|
|
43
|
+
except Exception:
|
|
44
|
+
_INSIGHTS = False
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
from services.forecasting import ForecastEngine
|
|
48
|
+
_FORECAST = True
|
|
49
|
+
except Exception:
|
|
50
|
+
_FORECAST = False
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if _FASTMCP:
|
|
54
|
+
mcp = FastMCP("AgentKit Business Intelligence")
|
|
55
|
+
else:
|
|
56
|
+
mcp = None # type: ignore
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
60
|
+
# TOOLS
|
|
61
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
62
|
+
|
|
63
|
+
def _records(df, limit: Optional[int] = None) -> List[Dict[str, Any]]:
|
|
64
|
+
"""DataFrame → JSON-safe list of dicts (numpy scalars → native, NaN/Inf → None)."""
|
|
65
|
+
import math
|
|
66
|
+
recs = df.to_dict("records")
|
|
67
|
+
if limit is not None:
|
|
68
|
+
recs = recs[:limit]
|
|
69
|
+
out: List[Dict[str, Any]] = []
|
|
70
|
+
for r in recs:
|
|
71
|
+
clean: Dict[str, Any] = {}
|
|
72
|
+
for k, v in r.items():
|
|
73
|
+
if hasattr(v, "item"): # numpy scalar
|
|
74
|
+
v = v.item()
|
|
75
|
+
if isinstance(v, float) and (math.isnan(v) or math.isinf(v)):
|
|
76
|
+
v = None
|
|
77
|
+
clean[k] = v
|
|
78
|
+
out.append(clean)
|
|
79
|
+
return out
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
async def query_kpis(
|
|
83
|
+
domain: Optional[str] = None,
|
|
84
|
+
period_from: Optional[str] = None,
|
|
85
|
+
period_to: Optional[str] = None,
|
|
86
|
+
metric_filter: Optional[str] = None,
|
|
87
|
+
limit: int = 100,
|
|
88
|
+
) -> Dict[str, Any]:
|
|
89
|
+
"""Return KPI metrics for a domain and period window."""
|
|
90
|
+
if not _PG:
|
|
91
|
+
raise RuntimeError("AgentKit data layer unavailable: set POSTGRES_URL and seed kpi_metrics")
|
|
92
|
+
try:
|
|
93
|
+
df = get_kpi_metrics(categories=[domain] if domain else None)
|
|
94
|
+
if df is None or df.empty:
|
|
95
|
+
return {"kpis": [], "total": 0}
|
|
96
|
+
if period_from:
|
|
97
|
+
df = df[df["period"] >= period_from]
|
|
98
|
+
if period_to:
|
|
99
|
+
df = df[df["period"] <= period_to]
|
|
100
|
+
if metric_filter:
|
|
101
|
+
df = df[df["metric"].str.contains(metric_filter, case=False, na=False)]
|
|
102
|
+
rows = _records(df, limit=limit)
|
|
103
|
+
return {"kpis": rows, "total": len(rows)}
|
|
104
|
+
except Exception as e:
|
|
105
|
+
log.exception("query_kpis failed: %s", e)
|
|
106
|
+
return {"kpis": [], "total": 0, "error": str(e)}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
async def get_company_health(domain: Optional[str] = None) -> Dict[str, Any]:
|
|
110
|
+
"""Return composite company health index for a domain (or all)."""
|
|
111
|
+
if not (_PG and _INSIGHTS):
|
|
112
|
+
raise RuntimeError("AgentKit data layer unavailable: set POSTGRES_URL and seed kpi_metrics")
|
|
113
|
+
try:
|
|
114
|
+
df = get_kpi_metrics(categories=[domain] if domain else None)
|
|
115
|
+
if df is None or df.empty:
|
|
116
|
+
return {"score": 0.0, "interpretation": "no_data", "components": {}}
|
|
117
|
+
h = compute_health_index(df)
|
|
118
|
+
return {
|
|
119
|
+
"score": float(h.get("score", 0.0)),
|
|
120
|
+
"interpretation": h.get("label", "n/a"),
|
|
121
|
+
"components": {k: h[k] for k in ("growth", "margin", "cash_score", "efficiency") if k in h},
|
|
122
|
+
}
|
|
123
|
+
except Exception as e:
|
|
124
|
+
log.exception("get_company_health failed: %s", e)
|
|
125
|
+
return {"score": 0.0, "interpretation": "error", "components": {}, "error": str(e)}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
async def detect_kpi_anomalies(
|
|
129
|
+
domain: str,
|
|
130
|
+
method: str = "zscore",
|
|
131
|
+
threshold: float = 2.5,
|
|
132
|
+
) -> Dict[str, Any]:
|
|
133
|
+
"""Find anomalies in a domain's KPI history."""
|
|
134
|
+
if not (_PG and _INSIGHTS):
|
|
135
|
+
raise RuntimeError("AgentKit data layer unavailable: set POSTGRES_URL and seed kpi_metrics")
|
|
136
|
+
try:
|
|
137
|
+
df = get_kpi_metrics(categories=[domain] if domain else None)
|
|
138
|
+
if df is None or df.empty:
|
|
139
|
+
return {"anomalies": [], "total": 0, "threshold": threshold, "method": method}
|
|
140
|
+
out = detect_anomalies(df, z_threshold=threshold, method=method)
|
|
141
|
+
if "is_anomaly" in out.columns:
|
|
142
|
+
out = out[out["is_anomaly"] == True] # noqa: E712
|
|
143
|
+
cols = [c for c in ("metric", "category", "period", "value", "z_score") if c in out.columns]
|
|
144
|
+
rows = _records(out[cols]) if not out.empty else []
|
|
145
|
+
return {"anomalies": rows, "total": len(rows), "threshold": threshold, "method": method}
|
|
146
|
+
except Exception as e:
|
|
147
|
+
log.exception("detect_kpi_anomalies failed: %s", e)
|
|
148
|
+
return {"anomalies": [], "total": 0, "threshold": threshold, "error": str(e)}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
async def forecast_metric(
|
|
152
|
+
metric_name: str,
|
|
153
|
+
periods: int = 6,
|
|
154
|
+
confidence_level: float = 0.95,
|
|
155
|
+
) -> Dict[str, Any]:
|
|
156
|
+
"""Forecast `periods` periods ahead for a named metric (Monte Carlo CI bands)."""
|
|
157
|
+
if not (_PG and _FORECAST):
|
|
158
|
+
raise RuntimeError("AgentKit data layer unavailable: set POSTGRES_URL and seed kpi_metrics")
|
|
159
|
+
try:
|
|
160
|
+
df = get_kpi_metrics(metrics=[metric_name])
|
|
161
|
+
if df is None or df.empty:
|
|
162
|
+
# name-tolerant fallback: case-insensitive exact, then substring match
|
|
163
|
+
alldf = get_kpi_metrics()
|
|
164
|
+
if alldf is not None and not alldf.empty:
|
|
165
|
+
exact = alldf[alldf["metric"].str.lower() == metric_name.lower()]
|
|
166
|
+
df = exact if not exact.empty else alldf[alldf["metric"].str.contains(metric_name, case=False, na=False)]
|
|
167
|
+
if df is None or df.empty:
|
|
168
|
+
return {"forecast": [], "upper_ci": [], "lower_ci": [], "method": "none", "note": "no_data"}
|
|
169
|
+
fdf = (df[["period", "value"]].rename(columns={"period": "month_tag", "value": "actual"})
|
|
170
|
+
.groupby("month_tag", as_index=False).agg({"actual": "mean"}).sort_values("month_tag"))
|
|
171
|
+
res = ForecastEngine().time_series_forecast(fdf, periods=periods, confidence_level=confidence_level)
|
|
172
|
+
if res is None or res.empty:
|
|
173
|
+
return {"forecast": [], "upper_ci": [], "lower_ci": [], "method": "none", "note": "insufficient_history"}
|
|
174
|
+
recs = res.to_dict("records")
|
|
175
|
+
return {
|
|
176
|
+
"metric": metric_name,
|
|
177
|
+
"forecast": [{"period": r["month_tag"], "value": round(float(r["forecast"]), 2)} for r in recs],
|
|
178
|
+
"lower_ci": [round(float(r["lower_bound"]), 2) for r in recs],
|
|
179
|
+
"upper_ci": [round(float(r["upper_bound"]), 2) for r in recs],
|
|
180
|
+
"confidence_level": confidence_level,
|
|
181
|
+
"method": "linear_regression",
|
|
182
|
+
}
|
|
183
|
+
except Exception as e:
|
|
184
|
+
log.exception("forecast_metric failed: %s", e)
|
|
185
|
+
return {"forecast": [], "upper_ci": [], "lower_ci": [], "method": "error", "error": str(e)}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
async def list_available_metrics(domain: Optional[str] = None) -> Dict[str, Any]:
|
|
189
|
+
"""Discovery tool: list metrics, categories, and periods (metrics scoped to domain if given)."""
|
|
190
|
+
if not _PG:
|
|
191
|
+
raise RuntimeError("AgentKit data layer unavailable: set POSTGRES_URL and seed kpi_metrics")
|
|
192
|
+
try:
|
|
193
|
+
metrics = get_available_metrics() or []
|
|
194
|
+
if domain:
|
|
195
|
+
df = get_kpi_metrics(categories=[domain])
|
|
196
|
+
if df is not None and not df.empty:
|
|
197
|
+
metrics = sorted(df["metric"].unique().tolist())
|
|
198
|
+
return {
|
|
199
|
+
"metrics": metrics,
|
|
200
|
+
"categories": get_available_categories() or [],
|
|
201
|
+
"periods": get_available_periods() or [],
|
|
202
|
+
}
|
|
203
|
+
except Exception as e:
|
|
204
|
+
log.exception("list_available_metrics failed: %s", e)
|
|
205
|
+
return {"metrics": [], "categories": [], "periods": [], "error": str(e)}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
async def get_executive_summary() -> Dict[str, Any]:
|
|
209
|
+
"""Synthesize health, KPIs, and anomalies into a one-shot executive summary."""
|
|
210
|
+
health = await get_company_health()
|
|
211
|
+
kpis = await query_kpis(limit=10)
|
|
212
|
+
anomalies = await detect_kpi_anomalies(domain="Finance") if _PG and _INSIGHTS else {"anomalies": []}
|
|
213
|
+
return {
|
|
214
|
+
"summary": "Executive snapshot generated by AgentKit",
|
|
215
|
+
"health_score": health.get("score", 0.0),
|
|
216
|
+
"interpretation": health.get("interpretation", "n/a"),
|
|
217
|
+
"components": health.get("components", {}),
|
|
218
|
+
"key_metrics": kpis.get("kpis", [])[:5],
|
|
219
|
+
"anomalies": anomalies.get("anomalies", [])[:5],
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
224
|
+
# Register with FastMCP (if available)
|
|
225
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
226
|
+
|
|
227
|
+
if _FASTMCP:
|
|
228
|
+
mcp.tool()(query_kpis)
|
|
229
|
+
mcp.tool()(get_company_health)
|
|
230
|
+
mcp.tool()(detect_kpi_anomalies)
|
|
231
|
+
mcp.tool()(forecast_metric)
|
|
232
|
+
mcp.tool()(list_available_metrics)
|
|
233
|
+
mcp.tool()(get_executive_summary)
|
|
234
|
+
|
|
235
|
+
@mcp.resource("kpi://Finance/latest")
|
|
236
|
+
async def finance_latest() -> Dict[str, Any]:
|
|
237
|
+
return await query_kpis(domain="Finance", limit=10)
|
|
238
|
+
|
|
239
|
+
@mcp.resource("kpi://Growth/latest")
|
|
240
|
+
async def growth_latest() -> Dict[str, Any]:
|
|
241
|
+
return await query_kpis(domain="Growth", limit=10)
|
|
242
|
+
|
|
243
|
+
@mcp.resource("kpi://Operations/latest")
|
|
244
|
+
async def ops_latest() -> Dict[str, Any]:
|
|
245
|
+
return await query_kpis(domain="Operations", limit=10)
|
|
246
|
+
|
|
247
|
+
@mcp.resource("kpi://People/latest")
|
|
248
|
+
async def people_latest() -> Dict[str, Any]:
|
|
249
|
+
return await query_kpis(domain="People", limit=10)
|
|
250
|
+
|
|
251
|
+
@mcp.resource("kpi://ESG/latest")
|
|
252
|
+
async def esg_latest() -> Dict[str, Any]:
|
|
253
|
+
return await query_kpis(domain="ESG", limit=10)
|
|
254
|
+
|
|
255
|
+
@mcp.resource("kpi://IT_Ops/latest")
|
|
256
|
+
async def itops_latest() -> Dict[str, Any]:
|
|
257
|
+
return await query_kpis(domain="IT_Ops", limit=10)
|
|
258
|
+
|
|
259
|
+
@mcp.prompt("monthly_executive_briefing")
|
|
260
|
+
def monthly_briefing(month: str = "this month") -> str:
|
|
261
|
+
return (
|
|
262
|
+
f"Produce a monthly executive briefing for {month}. "
|
|
263
|
+
"Sections: KEY FINDING, EVIDENCE (from KPI tools), ROOT CAUSE, "
|
|
264
|
+
"RECOMMENDED ACTION, RISK IF UNADDRESSED. Be concrete and concise."
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _serve_sse(port: int) -> None:
|
|
269
|
+
"""Serve SSE behind bearer-auth + rate-limit (gated by MCP_AUTH_TOKEN), composed with the
|
|
270
|
+
read-only web facade (REST /api + SPA). MCP paths (/sse, /messages, /demo) keep the exact
|
|
271
|
+
same middleware, auth and rate limit as before; everything else goes to the FastAPI facade.
|
|
272
|
+
Falls back to the plain FastMCP runner if the ASGI app can't be wrapped on this version."""
|
|
273
|
+
token = os.getenv("MCP_AUTH_TOKEN")
|
|
274
|
+
if not token:
|
|
275
|
+
log.warning("MCP_AUTH_TOKEN not set — SSE auth DISABLED (dev mode); rate-limit still on")
|
|
276
|
+
try:
|
|
277
|
+
import uvicorn
|
|
278
|
+
from auth_middleware import BearerAuthRateLimit
|
|
279
|
+
try:
|
|
280
|
+
app = mcp.http_app(transport="sse")
|
|
281
|
+
except TypeError:
|
|
282
|
+
app = mcp.http_app()
|
|
283
|
+
mcp_asgi = BearerAuthRateLimit(app)
|
|
284
|
+
|
|
285
|
+
try:
|
|
286
|
+
from web_app import build_app
|
|
287
|
+
api_asgi = build_app()
|
|
288
|
+
except Exception as e: # facade is additive — never block the MCP server on it
|
|
289
|
+
log.warning("web facade unavailable (%s) — serving MCP only", e)
|
|
290
|
+
api_asgi = None
|
|
291
|
+
|
|
292
|
+
if api_asgi is None:
|
|
293
|
+
composite = mcp_asgi
|
|
294
|
+
else:
|
|
295
|
+
_MCP_PREFIXES = ("/sse", "/messages", "/demo")
|
|
296
|
+
|
|
297
|
+
async def composite(scope, receive, send): # pure-ASGI dispatcher
|
|
298
|
+
if scope["type"] == "lifespan":
|
|
299
|
+
# The FastMCP session manager owns the lifespan; the facade has no startup hooks.
|
|
300
|
+
return await mcp_asgi(scope, receive, send)
|
|
301
|
+
path = scope.get("path", "")
|
|
302
|
+
if scope["type"] == "http" and path.startswith(_MCP_PREFIXES):
|
|
303
|
+
return await mcp_asgi(scope, receive, send)
|
|
304
|
+
return await api_asgi(scope, receive, send)
|
|
305
|
+
|
|
306
|
+
log.info("Serving SSE (auth=%s) + web facade on :%s", bool(token), port)
|
|
307
|
+
uvicorn.run(composite, host="0.0.0.0", port=port)
|
|
308
|
+
except Exception as e:
|
|
309
|
+
log.warning("guarded SSE serve unavailable (%s) — falling back to mcp.run(sse)", e)
|
|
310
|
+
mcp.run(transport="sse", host="0.0.0.0", port=port)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
if __name__ == "__main__":
|
|
314
|
+
if _FASTMCP:
|
|
315
|
+
# When a cloud platform injects $PORT, default to HTTP/SSE so the service is reachable;
|
|
316
|
+
# locally (no $PORT) default to stdio (the standard MCP transport for local clients).
|
|
317
|
+
transport = os.getenv("MCP_TRANSPORT") or ("sse" if os.getenv("PORT") else "stdio")
|
|
318
|
+
# Honor the platform-injected $PORT (Railway/Render/Fly) over MCP_PORT; default 8005.
|
|
319
|
+
port = int(os.getenv("MCP_PORT") or os.getenv("PORT") or "8005")
|
|
320
|
+
log.info("Starting AgentKit MCP server (transport=%s port=%s)...", transport, port)
|
|
321
|
+
if transport == "sse":
|
|
322
|
+
_serve_sse(port)
|
|
323
|
+
else:
|
|
324
|
+
mcp.run()
|
|
325
|
+
else:
|
|
326
|
+
log.error("fastmcp not installed; cannot start MCP server. pip install fastmcp")
|
web_app.py
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"""AgentKit web facade — read-only REST + SPA over the SAME functions the MCP tools use.
|
|
2
|
+
|
|
3
|
+
No business logic lives here: every /api endpoint delegates to the tool functions in
|
|
4
|
+
mcp_server.py (which call services/pg_store, services/insights, services/forecasting).
|
|
5
|
+
Data-layer failures surface as HTTP 503 with the real message — never fabricated data.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
from typing import Any, Dict, Optional
|
|
11
|
+
|
|
12
|
+
from fastapi import FastAPI, HTTPException
|
|
13
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
14
|
+
from fastapi.responses import FileResponse
|
|
15
|
+
from fastapi.staticfiles import StaticFiles
|
|
16
|
+
|
|
17
|
+
import mcp_server as tools
|
|
18
|
+
|
|
19
|
+
# Observability: in-memory request log (v1 "observability" ask) — real facade calls.
|
|
20
|
+
from collections import deque as _deque
|
|
21
|
+
from datetime import datetime as _dt
|
|
22
|
+
import time as _time
|
|
23
|
+
|
|
24
|
+
_OBS: "_deque[Dict[str, Any]]" = _deque(maxlen=200)
|
|
25
|
+
|
|
26
|
+
# Static metadata mirroring the six REAL tool signatures (mcp_server.py).
|
|
27
|
+
TOOL_META = [
|
|
28
|
+
{
|
|
29
|
+
"name": "query_kpis",
|
|
30
|
+
"description": "Return KPI metrics for a domain and period window.",
|
|
31
|
+
"params": [
|
|
32
|
+
{"name": "domain", "type": "string", "required": False},
|
|
33
|
+
{"name": "period_from", "type": "string", "required": False},
|
|
34
|
+
{"name": "period_to", "type": "string", "required": False},
|
|
35
|
+
{"name": "metric_filter", "type": "string", "required": False},
|
|
36
|
+
{"name": "limit", "type": "integer", "required": False, "default": 100},
|
|
37
|
+
],
|
|
38
|
+
"endpoint": "/api/kpis",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "get_company_health",
|
|
42
|
+
"description": "Composite company health index for a domain (or all).",
|
|
43
|
+
"params": [{"name": "domain", "type": "string", "required": False}],
|
|
44
|
+
"endpoint": "/api/health-score",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "detect_kpi_anomalies",
|
|
48
|
+
"description": "Find anomalies in a domain's KPI history (z-score).",
|
|
49
|
+
"params": [
|
|
50
|
+
{"name": "domain", "type": "string", "required": True},
|
|
51
|
+
{"name": "method", "type": "string", "required": False, "default": "zscore"},
|
|
52
|
+
{"name": "threshold", "type": "number", "required": False, "default": 2.5},
|
|
53
|
+
],
|
|
54
|
+
"endpoint": "/api/anomalies",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "forecast_metric",
|
|
58
|
+
"description": "Forecast N periods ahead for a named metric with CI bands.",
|
|
59
|
+
"params": [
|
|
60
|
+
{"name": "metric_name", "type": "string", "required": True},
|
|
61
|
+
{"name": "periods", "type": "integer", "required": False, "default": 6},
|
|
62
|
+
{"name": "confidence_level", "type": "number", "required": False, "default": 0.95},
|
|
63
|
+
],
|
|
64
|
+
"endpoint": "/api/forecast",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"name": "list_available_metrics",
|
|
68
|
+
"description": "Discovery: metrics, categories and periods available in the store.",
|
|
69
|
+
"params": [{"name": "domain", "type": "string", "required": False}],
|
|
70
|
+
"endpoint": "/api/metrics",
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "get_executive_summary",
|
|
74
|
+
"description": "One-shot synthesis of health, key KPIs and anomalies.",
|
|
75
|
+
"params": [],
|
|
76
|
+
"endpoint": "/api/summary",
|
|
77
|
+
},
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _guard(result: Dict[str, Any]) -> Dict[str, Any]:
|
|
82
|
+
return result
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
async def _call(fn, *args, **kwargs) -> Dict[str, Any]:
|
|
86
|
+
try:
|
|
87
|
+
return _guard(await fn(*args, **kwargs))
|
|
88
|
+
except RuntimeError as e: # tools raise when the data layer is unavailable
|
|
89
|
+
raise HTTPException(status_code=503, detail=str(e))
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def build_app() -> FastAPI:
|
|
93
|
+
app = FastAPI(title="AgentKit", version="0.1.0",
|
|
94
|
+
description="AI Agent Intelligence Platform — read-only facade over the MCP tools.")
|
|
95
|
+
|
|
96
|
+
# --- ETHICAL TELEMETRY ---
|
|
97
|
+
import threading
|
|
98
|
+
import requests
|
|
99
|
+
import os
|
|
100
|
+
import logging
|
|
101
|
+
|
|
102
|
+
def _send_telemetry():
|
|
103
|
+
if os.environ.get("TELEMETRY_OPT_OUT", "").lower() in ("1", "true", "yes"):
|
|
104
|
+
return
|
|
105
|
+
try:
|
|
106
|
+
logging.info("📡 Anonymous usage telemetry is ENABLED. This helps us understand project usage.")
|
|
107
|
+
logging.info("📡 To disable this, set the environment variable TELEMETRY_OPT_OUT=true.")
|
|
108
|
+
requests.post(
|
|
109
|
+
"https://gateway.ysiddo-ai-projects.app/telemetry",
|
|
110
|
+
json={"service": "AgentKit", "event": "startup"},
|
|
111
|
+
timeout=2
|
|
112
|
+
)
|
|
113
|
+
except Exception:
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
threading.Thread(target=_send_telemetry, daemon=True).start()
|
|
117
|
+
# -------------------------
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
from fastapi import Request
|
|
121
|
+
from fastapi.responses import JSONResponse
|
|
122
|
+
import os as _os
|
|
123
|
+
|
|
124
|
+
@app.middleware("http")
|
|
125
|
+
async def verify_internal_token(request: Request, call_next):
|
|
126
|
+
# Allow health checks and public auth routes
|
|
127
|
+
if request.url.path in ["/health", "/docs", "/openapi.json", "/api/redoc"] or request.url.path.startswith("/api/v1/auth/"):
|
|
128
|
+
return await call_next(request)
|
|
129
|
+
|
|
130
|
+
token = request.headers.get("X-OmniIntel-Internal-Token")
|
|
131
|
+
expected_token = _os.environ.get("OMNIINTEL_INTERNAL_TOKEN", "default-dev-token")
|
|
132
|
+
|
|
133
|
+
if token != expected_token and _os.environ.get("REQUIRE_INTERNAL_TOKEN", "true").lower() == "true":
|
|
134
|
+
return JSONResponse(status_code=403, content={"detail": "Missing or invalid X-OmniIntel-Internal-Token"})
|
|
135
|
+
|
|
136
|
+
return await call_next(request)
|
|
137
|
+
|
|
138
|
+
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["GET", "POST"], allow_headers=["*"])
|
|
139
|
+
|
|
140
|
+
@app.middleware("http")
|
|
141
|
+
async def _observe(request, call_next):
|
|
142
|
+
t0 = _time.time()
|
|
143
|
+
response = await call_next(request)
|
|
144
|
+
if request.url.path.startswith("/api"):
|
|
145
|
+
_OBS.appendleft({
|
|
146
|
+
"ts": _dt.utcnow().isoformat() + "Z",
|
|
147
|
+
"method": request.method,
|
|
148
|
+
"path": request.url.path,
|
|
149
|
+
"query": str(request.url.query or ""),
|
|
150
|
+
"status": response.status_code,
|
|
151
|
+
"ms": round((_time.time() - t0) * 1000, 1),
|
|
152
|
+
})
|
|
153
|
+
return response
|
|
154
|
+
|
|
155
|
+
@app.get("/health", include_in_schema=False)
|
|
156
|
+
async def health() -> Dict[str, Any]:
|
|
157
|
+
return {"status": "ok", "service": "agentkit", "version": "0.1.0"}
|
|
158
|
+
|
|
159
|
+
@app.get("/api/tools")
|
|
160
|
+
async def list_tools() -> Dict[str, Any]:
|
|
161
|
+
return {"tools": TOOL_META, "resources": [f"kpi://{d}/latest" for d in
|
|
162
|
+
("Finance", "Growth", "Operations", "People", "ESG", "IT_Ops")],
|
|
163
|
+
"prompts": ["monthly_executive_briefing"]}
|
|
164
|
+
|
|
165
|
+
@app.get("/api/kpis")
|
|
166
|
+
async def kpis(domain: Optional[str] = None, period_from: Optional[str] = None,
|
|
167
|
+
period_to: Optional[str] = None, metric_filter: Optional[str] = None,
|
|
168
|
+
limit: int = 100) -> Dict[str, Any]:
|
|
169
|
+
return await _call(tools.query_kpis, domain=domain, period_from=period_from,
|
|
170
|
+
period_to=period_to, metric_filter=metric_filter, limit=limit)
|
|
171
|
+
|
|
172
|
+
@app.get("/api/health-score")
|
|
173
|
+
async def health_score(domain: Optional[str] = None) -> Dict[str, Any]:
|
|
174
|
+
return await _call(tools.get_company_health, domain=domain)
|
|
175
|
+
|
|
176
|
+
@app.get("/api/anomalies")
|
|
177
|
+
async def anomalies(domain: str, method: str = "zscore", threshold: float = 2.5) -> Dict[str, Any]:
|
|
178
|
+
return await _call(tools.detect_kpi_anomalies, domain=domain, method=method, threshold=threshold)
|
|
179
|
+
|
|
180
|
+
@app.get("/api/forecast")
|
|
181
|
+
async def forecast(metric: str, periods: int = 6, confidence_level: float = 0.95) -> Dict[str, Any]:
|
|
182
|
+
return await _call(tools.forecast_metric, metric_name=metric, periods=periods,
|
|
183
|
+
confidence_level=confidence_level)
|
|
184
|
+
|
|
185
|
+
@app.get("/api/metrics")
|
|
186
|
+
async def metrics(domain: Optional[str] = None) -> Dict[str, Any]:
|
|
187
|
+
return await _call(tools.list_available_metrics, domain=domain)
|
|
188
|
+
|
|
189
|
+
@app.get("/api/summary")
|
|
190
|
+
async def summary() -> Dict[str, Any]:
|
|
191
|
+
return await _call(tools.get_executive_summary)
|
|
192
|
+
|
|
193
|
+
@app.get("/api/observability")
|
|
194
|
+
async def observability(limit: int = 100) -> Dict[str, Any]:
|
|
195
|
+
"""Recent facade requests (method, path, status, latency) — real observability."""
|
|
196
|
+
return {"requests": list(_OBS)[:limit], "capacity": _OBS.maxlen}
|
|
197
|
+
|
|
198
|
+
@app.post("/api/workflow/run")
|
|
199
|
+
async def workflow_run(body: Dict[str, Any]) -> Dict[str, Any]:
|
|
200
|
+
"""Execute the real 3-agent LangGraph workflow (planner → analyst → reporter).
|
|
201
|
+
Runs in a thread — the graph uses asyncio.run internally. Spends LLM credits."""
|
|
202
|
+
question = (body or {}).get("question", "").strip()
|
|
203
|
+
if not question:
|
|
204
|
+
raise HTTPException(status_code=400, detail="question required")
|
|
205
|
+
import anyio
|
|
206
|
+
try:
|
|
207
|
+
from workflow import analyze as run_workflow
|
|
208
|
+
except Exception as e:
|
|
209
|
+
raise HTTPException(status_code=501, detail=f"workflow_unavailable: {e}")
|
|
210
|
+
t0 = _time.time()
|
|
211
|
+
try:
|
|
212
|
+
result = await anyio.to_thread.run_sync(run_workflow, question)
|
|
213
|
+
except Exception as e:
|
|
214
|
+
raise HTTPException(status_code=500, detail=f"workflow_failed: {e}")
|
|
215
|
+
result["_elapsed_ms"] = round((_time.time() - t0) * 1000, 1)
|
|
216
|
+
return result
|
|
217
|
+
|
|
218
|
+
@app.get("/", include_in_schema=False)
|
|
219
|
+
async def root() -> Dict[str, Any]:
|
|
220
|
+
return {"service": "agentkit", "docs": "/docs", "mcp_sse": "/sse"}
|
|
221
|
+
|
|
222
|
+
return app
|