casual-mcp 0.5.0__py3-none-any.whl → 0.6.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.
- casual_mcp/__init__.py +4 -0
- casual_mcp/main.py +33 -7
- casual_mcp/mcp_tool_chat.py +73 -8
- casual_mcp/models/__init__.py +8 -0
- casual_mcp/models/chat_stats.py +37 -0
- {casual_mcp-0.5.0.dist-info → casual_mcp-0.6.0.dist-info}/METADATA +69 -8
- {casual_mcp-0.5.0.dist-info → casual_mcp-0.6.0.dist-info}/RECORD +11 -10
- {casual_mcp-0.5.0.dist-info → casual_mcp-0.6.0.dist-info}/WHEEL +0 -0
- {casual_mcp-0.5.0.dist-info → casual_mcp-0.6.0.dist-info}/entry_points.txt +0 -0
- {casual_mcp-0.5.0.dist-info → casual_mcp-0.6.0.dist-info}/licenses/LICENSE +0 -0
- {casual_mcp-0.5.0.dist-info → casual_mcp-0.6.0.dist-info}/top_level.txt +0 -0
casual_mcp/__init__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from importlib.metadata import version
|
|
2
2
|
|
|
3
3
|
from . import models
|
|
4
|
+
from .models.chat_stats import ChatStats, TokenUsageStats, ToolCallStats
|
|
4
5
|
|
|
5
6
|
__version__ = version("casual-mcp")
|
|
6
7
|
from .mcp_tool_chat import McpToolChat
|
|
@@ -17,4 +18,7 @@ __all__ = [
|
|
|
17
18
|
"load_mcp_client",
|
|
18
19
|
"render_system_prompt",
|
|
19
20
|
"models",
|
|
21
|
+
"ChatStats",
|
|
22
|
+
"TokenUsageStats",
|
|
23
|
+
"ToolCallStats",
|
|
20
24
|
]
|
casual_mcp/main.py
CHANGED
|
@@ -45,28 +45,54 @@ class GenerateRequest(BaseModel):
|
|
|
45
45
|
model: str = Field(title="Model to use")
|
|
46
46
|
system_prompt: str | None = Field(default=None, title="System Prompt to use")
|
|
47
47
|
prompt: str = Field(title="User Prompt")
|
|
48
|
+
include_stats: bool = Field(default=False, title="Include usage statistics in response")
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
class ChatRequest(BaseModel):
|
|
51
52
|
model: str = Field(title="Model to use")
|
|
52
53
|
system_prompt: str | None = Field(default=None, title="System Prompt to use")
|
|
53
54
|
messages: list[ChatMessage] = Field(title="Previous messages to supply to the LLM")
|
|
55
|
+
include_stats: bool = Field(default=False, title="Include usage statistics in response")
|
|
54
56
|
|
|
55
57
|
|
|
56
58
|
@app.post("/chat")
|
|
57
59
|
async def chat(req: ChatRequest) -> dict[str, Any]:
|
|
58
|
-
|
|
59
|
-
messages = await
|
|
60
|
+
chat_instance = await get_chat(req.model, req.system_prompt)
|
|
61
|
+
messages = await chat_instance.chat(req.messages)
|
|
60
62
|
|
|
61
|
-
|
|
63
|
+
if not messages:
|
|
64
|
+
error_result: dict[str, Any] = {"messages": [], "response": ""}
|
|
65
|
+
if req.include_stats:
|
|
66
|
+
error_result["stats"] = chat_instance.get_stats()
|
|
67
|
+
raise HTTPException(
|
|
68
|
+
status_code=500,
|
|
69
|
+
detail={"error": "No response generated", **error_result},
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
result: dict[str, Any] = {"messages": messages, "response": messages[-1].content}
|
|
73
|
+
if req.include_stats:
|
|
74
|
+
result["stats"] = chat_instance.get_stats()
|
|
75
|
+
return result
|
|
62
76
|
|
|
63
77
|
|
|
64
78
|
@app.post("/generate")
|
|
65
79
|
async def generate(req: GenerateRequest) -> dict[str, Any]:
|
|
66
|
-
|
|
67
|
-
messages = await
|
|
68
|
-
|
|
69
|
-
|
|
80
|
+
chat_instance = await get_chat(req.model, req.system_prompt)
|
|
81
|
+
messages = await chat_instance.generate(req.prompt, req.session_id)
|
|
82
|
+
|
|
83
|
+
if not messages:
|
|
84
|
+
error_result: dict[str, Any] = {"messages": [], "response": ""}
|
|
85
|
+
if req.include_stats:
|
|
86
|
+
error_result["stats"] = chat_instance.get_stats()
|
|
87
|
+
raise HTTPException(
|
|
88
|
+
status_code=500,
|
|
89
|
+
detail={"error": "No response generated", **error_result},
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
result: dict[str, Any] = {"messages": messages, "response": messages[-1].content}
|
|
93
|
+
if req.include_stats:
|
|
94
|
+
result["stats"] = chat_instance.get_stats()
|
|
95
|
+
return result
|
|
70
96
|
|
|
71
97
|
|
|
72
98
|
@app.get("/generate/session/{session_id}")
|
casual_mcp/mcp_tool_chat.py
CHANGED
|
@@ -14,6 +14,7 @@ from fastmcp import Client
|
|
|
14
14
|
|
|
15
15
|
from casual_mcp.convert_tools import tools_from_mcp
|
|
16
16
|
from casual_mcp.logging import get_logger
|
|
17
|
+
from casual_mcp.models.chat_stats import ChatStats
|
|
17
18
|
from casual_mcp.tool_cache import ToolCache
|
|
18
19
|
from casual_mcp.utils import format_tool_call_result
|
|
19
20
|
|
|
@@ -50,12 +51,35 @@ class McpToolChat:
|
|
|
50
51
|
self.system = system
|
|
51
52
|
self.tool_cache = tool_cache or ToolCache(mcp_client)
|
|
52
53
|
self._tool_cache_version = -1
|
|
54
|
+
self._last_stats: ChatStats | None = None
|
|
53
55
|
|
|
54
56
|
@staticmethod
|
|
55
57
|
def get_session(session_id: str) -> list[ChatMessage] | None:
|
|
56
58
|
global sessions
|
|
57
59
|
return sessions.get(session_id)
|
|
58
60
|
|
|
61
|
+
def get_stats(self) -> ChatStats | None:
|
|
62
|
+
"""
|
|
63
|
+
Get usage statistics from the last chat() or generate() call.
|
|
64
|
+
|
|
65
|
+
Returns None if no calls have been made yet.
|
|
66
|
+
Stats are reset at the start of each new chat()/generate() call.
|
|
67
|
+
"""
|
|
68
|
+
return self._last_stats
|
|
69
|
+
|
|
70
|
+
def _extract_server_from_tool_name(self, tool_name: str) -> str:
|
|
71
|
+
"""
|
|
72
|
+
Extract server name from a tool name.
|
|
73
|
+
|
|
74
|
+
With multiple servers, fastmcp prefixes tools as "serverName_toolName".
|
|
75
|
+
With a single server, tools are not prefixed.
|
|
76
|
+
|
|
77
|
+
Returns the server name or "default" if it cannot be determined.
|
|
78
|
+
"""
|
|
79
|
+
if "_" in tool_name:
|
|
80
|
+
return tool_name.split("_", 1)[0]
|
|
81
|
+
return "default"
|
|
82
|
+
|
|
59
83
|
async def generate(self, prompt: str, session_id: str | None = None) -> list[ChatMessage]:
|
|
60
84
|
# Fetch the session if we have a session ID
|
|
61
85
|
messages: list[ChatMessage]
|
|
@@ -84,6 +108,9 @@ class McpToolChat:
|
|
|
84
108
|
async def chat(self, messages: list[ChatMessage]) -> list[ChatMessage]:
|
|
85
109
|
tools = await self.tool_cache.get_tools()
|
|
86
110
|
|
|
111
|
+
# Reset stats at the start of each chat
|
|
112
|
+
self._last_stats = ChatStats()
|
|
113
|
+
|
|
87
114
|
# Add a system message if required
|
|
88
115
|
has_system_message = any(message.role == "system" for message in messages)
|
|
89
116
|
if self.system and not has_system_message:
|
|
@@ -97,6 +124,15 @@ class McpToolChat:
|
|
|
97
124
|
logger.info("Calling the LLM")
|
|
98
125
|
ai_message = await self.provider.chat(messages=messages, tools=tools_from_mcp(tools))
|
|
99
126
|
|
|
127
|
+
# Accumulate token usage stats
|
|
128
|
+
self._last_stats.llm_calls += 1
|
|
129
|
+
usage = self.provider.get_usage()
|
|
130
|
+
if usage:
|
|
131
|
+
prompt_tokens = getattr(usage, "prompt_tokens", 0) or 0
|
|
132
|
+
completion_tokens = getattr(usage, "completion_tokens", 0) or 0
|
|
133
|
+
self._last_stats.tokens.prompt_tokens += prompt_tokens
|
|
134
|
+
self._last_stats.tokens.completion_tokens += completion_tokens
|
|
135
|
+
|
|
100
136
|
# Add the assistant's message
|
|
101
137
|
response_messages.append(ai_message)
|
|
102
138
|
messages.append(ai_message)
|
|
@@ -108,6 +144,16 @@ class McpToolChat:
|
|
|
108
144
|
logger.info(f"Executing {len(ai_message.tool_calls)} tool calls")
|
|
109
145
|
result_count = 0
|
|
110
146
|
for tool_call in ai_message.tool_calls:
|
|
147
|
+
# Track tool call stats
|
|
148
|
+
tool_name = tool_call.function.name
|
|
149
|
+
self._last_stats.tool_calls.by_tool[tool_name] = (
|
|
150
|
+
self._last_stats.tool_calls.by_tool.get(tool_name, 0) + 1
|
|
151
|
+
)
|
|
152
|
+
server_name = self._extract_server_from_tool_name(tool_name)
|
|
153
|
+
self._last_stats.tool_calls.by_server[server_name] = (
|
|
154
|
+
self._last_stats.tool_calls.by_server.get(server_name, 0) + 1
|
|
155
|
+
)
|
|
156
|
+
|
|
111
157
|
try:
|
|
112
158
|
result = await self.execute(tool_call)
|
|
113
159
|
except Exception as e:
|
|
@@ -148,16 +194,35 @@ class McpToolChat:
|
|
|
148
194
|
logger.debug(f"Tool Call Result: {result}")
|
|
149
195
|
|
|
150
196
|
result_format = os.getenv("TOOL_RESULT_FORMAT", "result")
|
|
151
|
-
|
|
152
|
-
|
|
197
|
+
|
|
198
|
+
# Prefer structuredContent when available (machine-readable format)
|
|
199
|
+
# Note: MCP types use camelCase (structuredContent), mypy stubs may differ
|
|
200
|
+
structured = getattr(result, "structuredContent", None)
|
|
201
|
+
if structured is not None:
|
|
202
|
+
try:
|
|
203
|
+
content_text = json.dumps(structured)
|
|
204
|
+
except (TypeError, ValueError):
|
|
205
|
+
content_text = str(structured)
|
|
206
|
+
elif not result.content:
|
|
153
207
|
content_text = "[No content returned]"
|
|
154
208
|
else:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
209
|
+
# Fall back to processing content items
|
|
210
|
+
content_parts: list[Any] = []
|
|
211
|
+
for content_item in result.content:
|
|
212
|
+
if content_item.type == "text":
|
|
213
|
+
try:
|
|
214
|
+
parsed = json.loads(content_item.text)
|
|
215
|
+
content_parts.append(parsed)
|
|
216
|
+
except json.JSONDecodeError:
|
|
217
|
+
content_parts.append(content_item.text)
|
|
218
|
+
elif hasattr(content_item, "mimeType"):
|
|
219
|
+
# Image or audio content
|
|
220
|
+
content_parts.append(f"[{content_item.type}: {content_item.mimeType}]")
|
|
221
|
+
else:
|
|
222
|
+
content_parts.append(str(content_item))
|
|
223
|
+
|
|
224
|
+
content_text = json.dumps(content_parts)
|
|
225
|
+
|
|
161
226
|
content = format_tool_call_result(tool_call, content_text, style=result_format)
|
|
162
227
|
|
|
163
228
|
return ToolResultMessage(
|
casual_mcp/models/__init__.py
CHANGED
|
@@ -7,6 +7,11 @@ from casual_llm import (
|
|
|
7
7
|
UserMessage,
|
|
8
8
|
)
|
|
9
9
|
|
|
10
|
+
from .chat_stats import (
|
|
11
|
+
ChatStats,
|
|
12
|
+
TokenUsageStats,
|
|
13
|
+
ToolCallStats,
|
|
14
|
+
)
|
|
10
15
|
from .mcp_server_config import (
|
|
11
16
|
McpServerConfig,
|
|
12
17
|
RemoteServerConfig,
|
|
@@ -25,6 +30,9 @@ __all__ = [
|
|
|
25
30
|
"ToolResultMessage",
|
|
26
31
|
"SystemMessage",
|
|
27
32
|
"ChatMessage",
|
|
33
|
+
"ChatStats",
|
|
34
|
+
"TokenUsageStats",
|
|
35
|
+
"ToolCallStats",
|
|
28
36
|
"McpModelConfig",
|
|
29
37
|
"OllamaModelConfig",
|
|
30
38
|
"OpenAIModelConfig",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Usage statistics models for chat sessions."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field, computed_field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TokenUsageStats(BaseModel):
|
|
7
|
+
"""Token usage statistics accumulated across all LLM calls."""
|
|
8
|
+
|
|
9
|
+
prompt_tokens: int = Field(default=0, ge=0)
|
|
10
|
+
completion_tokens: int = Field(default=0, ge=0)
|
|
11
|
+
|
|
12
|
+
@computed_field # type: ignore[prop-decorator]
|
|
13
|
+
@property
|
|
14
|
+
def total_tokens(self) -> int:
|
|
15
|
+
"""Total tokens (prompt + completion)."""
|
|
16
|
+
return self.prompt_tokens + self.completion_tokens
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ToolCallStats(BaseModel):
|
|
20
|
+
"""Statistics about tool calls during a chat session."""
|
|
21
|
+
|
|
22
|
+
by_tool: dict[str, int] = Field(default_factory=dict)
|
|
23
|
+
by_server: dict[str, int] = Field(default_factory=dict)
|
|
24
|
+
|
|
25
|
+
@computed_field # type: ignore[prop-decorator]
|
|
26
|
+
@property
|
|
27
|
+
def total(self) -> int:
|
|
28
|
+
"""Total number of tool calls made."""
|
|
29
|
+
return sum(self.by_tool.values())
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ChatStats(BaseModel):
|
|
33
|
+
"""Combined statistics from a chat session."""
|
|
34
|
+
|
|
35
|
+
tokens: TokenUsageStats = Field(default_factory=TokenUsageStats)
|
|
36
|
+
tool_calls: ToolCallStats = Field(default_factory=ToolCallStats)
|
|
37
|
+
llm_calls: int = Field(default=0, ge=0, description="Number of LLM calls made")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: casual-mcp
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Multi-server MCP client for LLM tool orchestration
|
|
5
5
|
Author: Alex Stansfield
|
|
6
6
|
License: MIT
|
|
@@ -10,7 +10,7 @@ Project-URL: Issue Tracker, https://github.com/casualgenius/casual-mcp/issues
|
|
|
10
10
|
Requires-Python: >=3.10
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
|
-
Requires-Dist: casual-llm[openai]>=0.4.
|
|
13
|
+
Requires-Dist: casual-llm[openai]>=0.4.3
|
|
14
14
|
Requires-Dist: dateparser>=1.2.1
|
|
15
15
|
Requires-Dist: fastapi>=0.115.12
|
|
16
16
|
Requires-Dist: fastmcp>=2.12.4
|
|
@@ -33,6 +33,7 @@ It includes:
|
|
|
33
33
|
- ✅ A multi-server MCP client using [FastMCP](https://github.com/jlowin/fastmcp)
|
|
34
34
|
- ✅ Provider support for OpenAI and Ollama (powered by [casual-llm](https://github.com/AlexStansfield/casual-llm))
|
|
35
35
|
- ✅ A recursive tool-calling chat loop
|
|
36
|
+
- ✅ Usage statistics tracking (tokens, tool calls, LLM calls)
|
|
36
37
|
- ✅ System prompt templating with Jinja2
|
|
37
38
|
- ✅ A basic API exposing a chat endpoint
|
|
38
39
|
|
|
@@ -40,6 +41,7 @@ It includes:
|
|
|
40
41
|
|
|
41
42
|
- Plug-and-play multi-server tool orchestration
|
|
42
43
|
- OpenAI and Ollama LLM providers (via casual-llm)
|
|
44
|
+
- Usage statistics tracking (tokens, tool calls, LLM calls)
|
|
43
45
|
- Prompt templating with Jinja2
|
|
44
46
|
- Configurable via JSON
|
|
45
47
|
- CLI and API access
|
|
@@ -253,8 +255,39 @@ messages = [
|
|
|
253
255
|
UserMessage(content="What time is it in London?")
|
|
254
256
|
]
|
|
255
257
|
response = await chat.chat(messages)
|
|
258
|
+
|
|
259
|
+
# Get usage statistics from the last call
|
|
260
|
+
stats = chat.get_stats()
|
|
261
|
+
if stats:
|
|
262
|
+
print(f"Tokens used: {stats.tokens.total_tokens}")
|
|
263
|
+
print(f"Tool calls: {stats.tool_calls.total}")
|
|
264
|
+
print(f"LLM calls: {stats.llm_calls}")
|
|
256
265
|
```
|
|
257
266
|
|
|
267
|
+
#### Usage Statistics
|
|
268
|
+
|
|
269
|
+
After calling `chat()` or `generate()`, you can retrieve usage statistics via `get_stats()`:
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
response = await chat.chat(messages)
|
|
273
|
+
stats = chat.get_stats()
|
|
274
|
+
|
|
275
|
+
# Token usage (accumulated across all LLM calls in the agentic loop)
|
|
276
|
+
stats.tokens.prompt_tokens # Input tokens
|
|
277
|
+
stats.tokens.completion_tokens # Output tokens
|
|
278
|
+
stats.tokens.total_tokens # Total (computed)
|
|
279
|
+
|
|
280
|
+
# Tool call stats
|
|
281
|
+
stats.tool_calls.by_tool # Dict of tool name -> call count, e.g. {"math_add": 2}
|
|
282
|
+
stats.tool_calls.by_server # Dict of server name -> call count, e.g. {"math": 2}
|
|
283
|
+
stats.tool_calls.total # Total tool calls (computed)
|
|
284
|
+
|
|
285
|
+
# LLM call count
|
|
286
|
+
stats.llm_calls # Number of LLM calls made (1 = no tools, 2+ = tool loop)
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Stats are reset at the start of each new `chat()` or `generate()` call. Returns `None` if no calls have been made yet.
|
|
290
|
+
|
|
258
291
|
#### `ProviderFactory`
|
|
259
292
|
Instantiates LLM providers (from casual-llm) based on the selected model config.
|
|
260
293
|
|
|
@@ -294,6 +327,9 @@ Exported from `casual_mcp.models`:
|
|
|
294
327
|
- `RemoteServerConfig`
|
|
295
328
|
- `OpenAIModelConfig`
|
|
296
329
|
- `OllamaModelConfig`
|
|
330
|
+
- `ChatStats`
|
|
331
|
+
- `TokenUsageStats`
|
|
332
|
+
- `ToolCallStats`
|
|
297
333
|
|
|
298
334
|
Use these types to build valid configs:
|
|
299
335
|
|
|
@@ -582,9 +618,10 @@ casual-mcp serve --host 0.0.0.0 --port 8000
|
|
|
582
618
|
#### Request Body:
|
|
583
619
|
- `model`: the LLM model to use
|
|
584
620
|
- `messages`: list of chat messages (system, assistant, user, etc) that you can pass to the api, allowing you to keep your own chat session in the client calling the api
|
|
621
|
+
- `include_stats`: (optional, default: `false`) include usage statistics in the response
|
|
585
622
|
|
|
586
623
|
#### Example:
|
|
587
|
-
```
|
|
624
|
+
```json
|
|
588
625
|
{
|
|
589
626
|
"model": "gpt-4.1-nano",
|
|
590
627
|
"messages": [
|
|
@@ -592,13 +629,35 @@ casual-mcp serve --host 0.0.0.0 --port 8000
|
|
|
592
629
|
"role": "user",
|
|
593
630
|
"content": "can you explain what the word consistent means?"
|
|
594
631
|
}
|
|
595
|
-
]
|
|
632
|
+
],
|
|
633
|
+
"include_stats": true
|
|
634
|
+
}
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
#### Response with stats:
|
|
638
|
+
```json
|
|
639
|
+
{
|
|
640
|
+
"messages": [...],
|
|
641
|
+
"response": "Consistent means...",
|
|
642
|
+
"stats": {
|
|
643
|
+
"tokens": {
|
|
644
|
+
"prompt_tokens": 150,
|
|
645
|
+
"completion_tokens": 75,
|
|
646
|
+
"total_tokens": 225
|
|
647
|
+
},
|
|
648
|
+
"tool_calls": {
|
|
649
|
+
"by_tool": {"words_define": 1},
|
|
650
|
+
"by_server": {"words": 1},
|
|
651
|
+
"total": 1
|
|
652
|
+
},
|
|
653
|
+
"llm_calls": 2
|
|
654
|
+
}
|
|
596
655
|
}
|
|
597
656
|
```
|
|
598
657
|
|
|
599
658
|
### Generate
|
|
600
659
|
|
|
601
|
-
The generate endpoint allows you to send a user prompt as a string.
|
|
660
|
+
The generate endpoint allows you to send a user prompt as a string.
|
|
602
661
|
|
|
603
662
|
It also support sessions that keep a record of all messages in the session and feeds them back into the LLM for context. Sessions are stored in memory so are cleared when the server is restarted
|
|
604
663
|
|
|
@@ -606,15 +665,17 @@ It also support sessions that keep a record of all messages in the session and f
|
|
|
606
665
|
|
|
607
666
|
#### Request Body:
|
|
608
667
|
- `model`: the LLM model to use
|
|
609
|
-
- `prompt`: the user prompt
|
|
668
|
+
- `prompt`: the user prompt
|
|
610
669
|
- `session_id`: an optional ID that stores all the messages from the session and provides them back to the LLM for context
|
|
670
|
+
- `include_stats`: (optional, default: `false`) include usage statistics in the response
|
|
611
671
|
|
|
612
672
|
#### Example:
|
|
613
|
-
```
|
|
673
|
+
```json
|
|
614
674
|
{
|
|
615
675
|
"session_id": "my-session",
|
|
616
676
|
"model": "gpt-4o-mini",
|
|
617
|
-
"prompt": "can you explain what the word consistent means?"
|
|
677
|
+
"prompt": "can you explain what the word consistent means?",
|
|
678
|
+
"include_stats": true
|
|
618
679
|
}
|
|
619
680
|
```
|
|
620
681
|
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
casual_mcp/__init__.py,sha256=
|
|
1
|
+
casual_mcp/__init__.py,sha256=eeI1TIj8Cu-H4OMV64LaNqVqo4wSFaGu7215hJeN_HM,598
|
|
2
2
|
casual_mcp/cli.py,sha256=2-0sTxfNfQSukBtg0Xs9P6VrAMZ89SqJ9VJzOM68d-o,2129
|
|
3
3
|
casual_mcp/convert_tools.py,sha256=mlH18DTGGeWb0Vxfj1cUSMhTGRE9z8q_xWrVXvpg3mE,1742
|
|
4
4
|
casual_mcp/logging.py,sha256=S2XpLIKHHDtmru_YBFLdMamdmYRm16Yw3tshE3g3Wqg,932
|
|
5
|
-
casual_mcp/main.py,sha256=
|
|
6
|
-
casual_mcp/mcp_tool_chat.py,sha256=
|
|
5
|
+
casual_mcp/main.py,sha256=aI3isW0Wzny_iubx8HlNgBVvYEeBe-Jrrdbp80oYmk4,4299
|
|
6
|
+
casual_mcp/mcp_tool_chat.py,sha256=Evc5LMfUYicl7jlix42QURYaq0cI2CIUg0q-344cjUg,8401
|
|
7
7
|
casual_mcp/provider_factory.py,sha256=Jp2HQOJdlDDed-hfZf1drEVbw0kpZSE0TN9G0Dcp4w8,1260
|
|
8
8
|
casual_mcp/tool_cache.py,sha256=VE599sF7vHH6megcueqVxCZavvTcoFDoZu2QuZM3cYA,3161
|
|
9
9
|
casual_mcp/utils.py,sha256=XxzPxQ3j97edeCRXtoO8lJS9R0JYOa25p2MJNwGapJA,3201
|
|
10
|
-
casual_mcp/models/__init__.py,sha256=
|
|
10
|
+
casual_mcp/models/__init__.py,sha256=byhteS6fueIdtoaQYL2w5hcBJmJhXF7X7YhGslvscco,786
|
|
11
|
+
casual_mcp/models/chat_stats.py,sha256=ZjeZ_ckx-SfioYs39NAaQxK6qPG9SlFlrB7j7jHZ40w,1221
|
|
11
12
|
casual_mcp/models/config.py,sha256=LcqtfW3w7iqrT3FnW50L1mgqAvD_OsYk4ySBZZVV-GI,300
|
|
12
13
|
casual_mcp/models/generation_error.py,sha256=abDAahS2fhYkS-ARng1Tk7oudoAO4imkoKYcC9PHT2U,272
|
|
13
14
|
casual_mcp/models/mcp_server_config.py,sha256=0OHsHUEKxRoCl21lsye4E5GoCNmdZWIZCOOthcTpdsE,539
|
|
14
15
|
casual_mcp/models/model_config.py,sha256=59Y7MvcboPKdAilSwUyeC7lfRm4aYkFhZ5c8EVRP5ys,425
|
|
15
|
-
casual_mcp-0.
|
|
16
|
-
casual_mcp-0.
|
|
17
|
-
casual_mcp-0.
|
|
18
|
-
casual_mcp-0.
|
|
19
|
-
casual_mcp-0.
|
|
20
|
-
casual_mcp-0.
|
|
16
|
+
casual_mcp-0.6.0.dist-info/licenses/LICENSE,sha256=U3Zu2tkrh5vXdy7gIdE8WJGM9D4gGp3hohAAWdre-yo,1058
|
|
17
|
+
casual_mcp-0.6.0.dist-info/METADATA,sha256=GQLuEXfducugyuUHjB3qklz8FAOZ7go3PQ0d7Pqb2ZI,22218
|
|
18
|
+
casual_mcp-0.6.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
19
|
+
casual_mcp-0.6.0.dist-info/entry_points.txt,sha256=X48Np2cwl-SlRQdV26y2vPZ-2tJaODgZeVtfpHho-zg,50
|
|
20
|
+
casual_mcp-0.6.0.dist-info/top_level.txt,sha256=K4CiI0Jf8PHICjuQVm32HuNMB44kp8Lb02bbbdiH5bo,11
|
|
21
|
+
casual_mcp-0.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|