casual-mcp 0.6.0__py3-none-any.whl → 0.7.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/cli.py +379 -6
- casual_mcp/main.py +62 -3
- casual_mcp/mcp_tool_chat.py +79 -7
- casual_mcp/models/__init__.py +8 -0
- casual_mcp/models/config.py +3 -1
- casual_mcp/models/toolset_config.py +40 -0
- casual_mcp/tool_filter.py +171 -0
- casual_mcp-0.7.0.dist-info/METADATA +193 -0
- {casual_mcp-0.6.0.dist-info → casual_mcp-0.7.0.dist-info}/RECORD +13 -11
- casual_mcp-0.6.0.dist-info/METADATA +0 -691
- {casual_mcp-0.6.0.dist-info → casual_mcp-0.7.0.dist-info}/WHEEL +0 -0
- {casual_mcp-0.6.0.dist-info → casual_mcp-0.7.0.dist-info}/entry_points.txt +0 -0
- {casual_mcp-0.6.0.dist-info → casual_mcp-0.7.0.dist-info}/licenses/LICENSE +0 -0
- {casual_mcp-0.6.0.dist-info → casual_mcp-0.7.0.dist-info}/top_level.txt +0 -0
casual_mcp/models/config.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
from pydantic import BaseModel
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
2
|
|
|
3
3
|
from casual_mcp.models.mcp_server_config import McpServerConfig
|
|
4
4
|
from casual_mcp.models.model_config import McpModelConfig
|
|
5
|
+
from casual_mcp.models.toolset_config import ToolSetConfig
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class Config(BaseModel):
|
|
8
9
|
namespace_tools: bool | None = False
|
|
9
10
|
models: dict[str, McpModelConfig]
|
|
10
11
|
servers: dict[str, McpServerConfig]
|
|
12
|
+
tool_sets: dict[str, ToolSetConfig] = Field(default_factory=dict)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Toolset configuration models for filtering available tools."""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ExcludeSpec(BaseModel):
|
|
7
|
+
"""Specification for excluding specific tools from a server."""
|
|
8
|
+
|
|
9
|
+
exclude: list[str] = Field(description="List of tool names to exclude")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Tool specification: true (all), list (include specific), or exclude object
|
|
13
|
+
ToolSpec = bool | list[str] | ExcludeSpec
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ToolSetConfig(BaseModel):
|
|
17
|
+
"""Configuration for a named toolset.
|
|
18
|
+
|
|
19
|
+
A toolset defines which tools from which servers should be available
|
|
20
|
+
during a chat session. Each server can be configured to:
|
|
21
|
+
- Include all tools (True)
|
|
22
|
+
- Include specific tools (list of tool names)
|
|
23
|
+
- Include all except specific tools (ExcludeSpec)
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
{
|
|
27
|
+
"description": "Research tools",
|
|
28
|
+
"servers": {
|
|
29
|
+
"wikimedia": True,
|
|
30
|
+
"search": ["brave_web_search"],
|
|
31
|
+
"fetch": {"exclude": ["fetch_dangerous"]}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
description: str = Field(default="", description="Human-readable description")
|
|
37
|
+
servers: dict[str, ToolSpec] = Field(
|
|
38
|
+
default_factory=dict,
|
|
39
|
+
description="Mapping of server name to tool specification",
|
|
40
|
+
)
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""Tool filtering logic for toolsets.
|
|
2
|
+
|
|
3
|
+
This module provides functionality to filter MCP tools based on toolset
|
|
4
|
+
configurations, including validation to ensure referenced servers and
|
|
5
|
+
tools actually exist.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import mcp
|
|
9
|
+
|
|
10
|
+
from casual_mcp.logging import get_logger
|
|
11
|
+
from casual_mcp.models.toolset_config import ExcludeSpec, ToolSetConfig
|
|
12
|
+
|
|
13
|
+
logger = get_logger("tool_filter")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ToolSetValidationError(Exception):
|
|
17
|
+
"""Raised when a toolset references invalid servers or tools."""
|
|
18
|
+
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def extract_server_and_tool(tool_name: str, server_names: set[str]) -> tuple[str, str]:
|
|
23
|
+
"""Extract server name and base tool name from a potentially prefixed tool name.
|
|
24
|
+
|
|
25
|
+
When multiple servers are configured, fastmcp prefixes tools as "serverName_toolName".
|
|
26
|
+
When a single server is configured, tools are not prefixed.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
tool_name: The full tool name (possibly prefixed)
|
|
30
|
+
server_names: Set of configured server names
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Tuple of (server_name, base_tool_name)
|
|
34
|
+
"""
|
|
35
|
+
if "_" in tool_name:
|
|
36
|
+
prefix = tool_name.split("_", 1)[0]
|
|
37
|
+
if prefix in server_names:
|
|
38
|
+
return prefix, tool_name.split("_", 1)[1]
|
|
39
|
+
|
|
40
|
+
# Single server case - return the single server name
|
|
41
|
+
if len(server_names) == 1:
|
|
42
|
+
return next(iter(server_names)), tool_name
|
|
43
|
+
|
|
44
|
+
# Fallback - can't determine server
|
|
45
|
+
return "default", tool_name
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _build_server_tool_map(tools: list[mcp.Tool], server_names: set[str]) -> dict[str, set[str]]:
|
|
49
|
+
"""Build a mapping of server names to their available tool names.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
tools: List of MCP tools
|
|
53
|
+
server_names: Set of configured server names
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Dict mapping server name to set of base tool names
|
|
57
|
+
"""
|
|
58
|
+
server_tool_map: dict[str, set[str]] = {name: set() for name in server_names}
|
|
59
|
+
|
|
60
|
+
for tool in tools:
|
|
61
|
+
server_name, base_name = extract_server_and_tool(tool.name, server_names)
|
|
62
|
+
if server_name in server_tool_map:
|
|
63
|
+
server_tool_map[server_name].add(base_name)
|
|
64
|
+
|
|
65
|
+
return server_tool_map
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def validate_toolset(
|
|
69
|
+
toolset: ToolSetConfig,
|
|
70
|
+
tools: list[mcp.Tool],
|
|
71
|
+
server_names: set[str],
|
|
72
|
+
) -> None:
|
|
73
|
+
"""Validate that a toolset references only valid servers and tools.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
toolset: The toolset configuration to validate
|
|
77
|
+
tools: List of available MCP tools
|
|
78
|
+
server_names: Set of configured server names
|
|
79
|
+
|
|
80
|
+
Raises:
|
|
81
|
+
ToolSetValidationError: If the toolset references non-existent servers or tools
|
|
82
|
+
"""
|
|
83
|
+
server_tool_map = _build_server_tool_map(tools, server_names)
|
|
84
|
+
errors: list[str] = []
|
|
85
|
+
|
|
86
|
+
for server_name, tool_spec in toolset.servers.items():
|
|
87
|
+
# Check server exists
|
|
88
|
+
if server_name not in server_names:
|
|
89
|
+
errors.append(f"Server '{server_name}' not found in configuration")
|
|
90
|
+
continue
|
|
91
|
+
|
|
92
|
+
available = server_tool_map.get(server_name, set())
|
|
93
|
+
|
|
94
|
+
# Validate tool names in include list
|
|
95
|
+
if isinstance(tool_spec, list):
|
|
96
|
+
for tool_name in tool_spec:
|
|
97
|
+
if tool_name not in available:
|
|
98
|
+
errors.append(
|
|
99
|
+
f"Tool '{tool_name}' not found in server '{server_name}'. "
|
|
100
|
+
f"Available: {sorted(available)}"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# Validate tool names in exclude list
|
|
104
|
+
elif isinstance(tool_spec, ExcludeSpec):
|
|
105
|
+
for tool_name in tool_spec.exclude:
|
|
106
|
+
if tool_name not in available:
|
|
107
|
+
errors.append(
|
|
108
|
+
f"Tool '{tool_name}' not found in server '{server_name}' "
|
|
109
|
+
f"(specified in exclude list). Available: {sorted(available)}"
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
if errors:
|
|
113
|
+
raise ToolSetValidationError("\n".join(errors))
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def filter_tools_by_toolset(
|
|
117
|
+
tools: list[mcp.Tool],
|
|
118
|
+
toolset: ToolSetConfig,
|
|
119
|
+
server_names: set[str],
|
|
120
|
+
validate: bool = True,
|
|
121
|
+
) -> list[mcp.Tool]:
|
|
122
|
+
"""Filter a list of MCP tools based on a toolset configuration.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
tools: Full list of available MCP tools
|
|
126
|
+
toolset: The toolset configuration to apply
|
|
127
|
+
server_names: Set of configured server names
|
|
128
|
+
validate: Whether to validate the toolset first (raises on invalid)
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
Filtered list of tools matching the toolset
|
|
132
|
+
|
|
133
|
+
Raises:
|
|
134
|
+
ToolSetValidationError: If validate=True and toolset is invalid
|
|
135
|
+
"""
|
|
136
|
+
if validate:
|
|
137
|
+
validate_toolset(toolset, tools, server_names)
|
|
138
|
+
|
|
139
|
+
filtered: list[mcp.Tool] = []
|
|
140
|
+
|
|
141
|
+
for tool in tools:
|
|
142
|
+
server_name, base_name = extract_server_and_tool(tool.name, server_names)
|
|
143
|
+
|
|
144
|
+
# Check if this server is in the toolset
|
|
145
|
+
if server_name not in toolset.servers:
|
|
146
|
+
continue
|
|
147
|
+
|
|
148
|
+
tool_spec = toolset.servers[server_name]
|
|
149
|
+
|
|
150
|
+
# Determine if tool should be included
|
|
151
|
+
include = False
|
|
152
|
+
|
|
153
|
+
if tool_spec is True:
|
|
154
|
+
# All tools from this server
|
|
155
|
+
include = True
|
|
156
|
+
elif isinstance(tool_spec, list):
|
|
157
|
+
# Only specific tools
|
|
158
|
+
include = base_name in tool_spec
|
|
159
|
+
elif isinstance(tool_spec, ExcludeSpec):
|
|
160
|
+
# All except excluded tools
|
|
161
|
+
include = base_name not in tool_spec.exclude
|
|
162
|
+
|
|
163
|
+
if include:
|
|
164
|
+
filtered.append(tool)
|
|
165
|
+
|
|
166
|
+
logger.debug(
|
|
167
|
+
f"Filtered {len(tools)} tools to {len(filtered)} using toolset "
|
|
168
|
+
f"with {len(toolset.servers)} servers"
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
return filtered
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: casual-mcp
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: Multi-server MCP client for LLM tool orchestration
|
|
5
|
+
Author: Alex Stansfield
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/casualgenius/casual-mcp
|
|
8
|
+
Project-URL: Repository, https://github.com/casualgenius/casual-mcp
|
|
9
|
+
Project-URL: Issue Tracker, https://github.com/casualgenius/casual-mcp/issues
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: casual-llm[openai]>=0.4.3
|
|
14
|
+
Requires-Dist: dateparser>=1.2.1
|
|
15
|
+
Requires-Dist: fastapi>=0.115.12
|
|
16
|
+
Requires-Dist: fastmcp>=2.12.4
|
|
17
|
+
Requires-Dist: jinja2>=3.1.6
|
|
18
|
+
Requires-Dist: python-dotenv>=1.1.0
|
|
19
|
+
Requires-Dist: questionary>=2.1.0
|
|
20
|
+
Requires-Dist: requests>=2.32.3
|
|
21
|
+
Requires-Dist: rich>=14.0.0
|
|
22
|
+
Requires-Dist: typer>=0.19.2
|
|
23
|
+
Requires-Dist: uvicorn>=0.34.2
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# Casual MCP
|
|
27
|
+
|
|
28
|
+

|
|
29
|
+

|
|
30
|
+
|
|
31
|
+
**Casual MCP** is a Python framework for building, evaluating, and serving LLMs with tool-calling capabilities using [Model Context Protocol (MCP)](https://modelcontextprotocol.io).
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- Multi-server MCP client using [FastMCP](https://github.com/jlowin/fastmcp)
|
|
36
|
+
- OpenAI and Ollama provider support (via [casual-llm](https://github.com/AlexStansfield/casual-llm))
|
|
37
|
+
- Recursive tool-calling chat loop
|
|
38
|
+
- Toolsets for selective tool filtering per request
|
|
39
|
+
- Usage statistics tracking (tokens, tool calls, LLM calls)
|
|
40
|
+
- System prompt templating with Jinja2
|
|
41
|
+
- CLI and API interfaces
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Using uv
|
|
47
|
+
uv add casual-mcp
|
|
48
|
+
|
|
49
|
+
# Using pip
|
|
50
|
+
pip install casual-mcp
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For development:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
git clone https://github.com/casualgenius/casual-mcp.git
|
|
57
|
+
cd casual-mcp
|
|
58
|
+
uv sync --group dev
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Quick Start
|
|
62
|
+
|
|
63
|
+
1. Create `casual_mcp_config.json`:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"models": {
|
|
68
|
+
"gpt-4.1": { "provider": "openai", "model": "gpt-4.1" }
|
|
69
|
+
},
|
|
70
|
+
"servers": {
|
|
71
|
+
"time": { "command": "python", "args": ["mcp-servers/time/server.py"] }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
2. Set your API key: `export OPENAI_API_KEY=your-key`
|
|
77
|
+
|
|
78
|
+
3. Start the server: `casual-mcp serve`
|
|
79
|
+
|
|
80
|
+
4. Make a request:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
curl -X POST http://localhost:8000/generate \
|
|
84
|
+
-H "Content-Type: application/json" \
|
|
85
|
+
-d '{"model": "gpt-4.1", "prompt": "What time is it?"}'
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Configuration
|
|
89
|
+
|
|
90
|
+
Configure models, MCP servers, and toolsets in `casual_mcp_config.json`.
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"models": {
|
|
95
|
+
"gpt-4.1": { "provider": "openai", "model": "gpt-4.1" }
|
|
96
|
+
},
|
|
97
|
+
"servers": {
|
|
98
|
+
"time": { "command": "python", "args": ["server.py"] },
|
|
99
|
+
"weather": { "url": "http://localhost:5050/mcp" }
|
|
100
|
+
},
|
|
101
|
+
"tool_sets": {
|
|
102
|
+
"basic": { "description": "Basic tools", "servers": { "time": true } }
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
See [Configuration Guide](docs/configuration.md) for full details on models, servers, toolsets, and templates.
|
|
108
|
+
|
|
109
|
+
## CLI
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
casual-mcp serve # Start API server
|
|
113
|
+
casual-mcp servers # List configured servers
|
|
114
|
+
casual-mcp models # List configured models
|
|
115
|
+
casual-mcp toolsets # Manage toolsets interactively
|
|
116
|
+
casual-mcp tools # List available tools
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
See [CLI & API Reference](docs/cli-api.md) for all commands and options.
|
|
120
|
+
|
|
121
|
+
## API
|
|
122
|
+
|
|
123
|
+
| Endpoint | Description |
|
|
124
|
+
|----------|-------------|
|
|
125
|
+
| `POST /chat` | Send message history |
|
|
126
|
+
| `POST /generate` | Send prompt with optional session |
|
|
127
|
+
| `GET /generate/session/{id}` | Get session messages |
|
|
128
|
+
| `GET /toolsets` | List available toolsets |
|
|
129
|
+
|
|
130
|
+
See [CLI & API Reference](docs/cli-api.md#api-endpoints) for request/response formats.
|
|
131
|
+
|
|
132
|
+
## Programmatic Usage
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from casual_llm import SystemMessage, UserMessage
|
|
136
|
+
from casual_mcp import McpToolChat, ProviderFactory, load_config, load_mcp_client
|
|
137
|
+
|
|
138
|
+
config = load_config("casual_mcp_config.json")
|
|
139
|
+
mcp_client = load_mcp_client(config)
|
|
140
|
+
|
|
141
|
+
provider_factory = ProviderFactory()
|
|
142
|
+
provider = provider_factory.get_provider("gpt-4.1", config.models["gpt-4.1"])
|
|
143
|
+
|
|
144
|
+
chat = McpToolChat(mcp_client, provider)
|
|
145
|
+
messages = [
|
|
146
|
+
SystemMessage(content="You are a helpful assistant."),
|
|
147
|
+
UserMessage(content="What time is it?")
|
|
148
|
+
]
|
|
149
|
+
response = await chat.chat(messages)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
See [Programmatic Usage Guide](docs/programmatic-usage.md) for `McpToolChat`, usage statistics, toolsets, and common patterns.
|
|
153
|
+
|
|
154
|
+
## Architecture
|
|
155
|
+
|
|
156
|
+
Casual MCP orchestrates LLMs and MCP tool servers in a recursive loop:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
|
|
160
|
+
│ MCP Servers │─────▶│ Tool Cache │─────▶│ Tool Converter│
|
|
161
|
+
└─────────────┘ └──────────────┘ └─────────────┘
|
|
162
|
+
│ │
|
|
163
|
+
▼ ▼
|
|
164
|
+
┌──────────────────────────────┐
|
|
165
|
+
│ McpToolChat Loop │
|
|
166
|
+
│ │
|
|
167
|
+
│ LLM ──▶ Tool Calls ──▶ MCP │
|
|
168
|
+
│ ▲ │ │
|
|
169
|
+
│ └──────── Results ─────┘ │
|
|
170
|
+
└──────────────────────────────┘
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
1. **MCP Client** connects to tool servers (local stdio or remote HTTP/SSE)
|
|
174
|
+
2. **Tool Cache** fetches and caches tools from all servers
|
|
175
|
+
3. **ProviderFactory** creates LLM providers from casual-llm
|
|
176
|
+
4. **McpToolChat** runs the recursive loop until the LLM provides a final answer
|
|
177
|
+
|
|
178
|
+
## Environment Variables
|
|
179
|
+
|
|
180
|
+
| Variable | Default | Description |
|
|
181
|
+
|----------|---------|-------------|
|
|
182
|
+
| `OPENAI_API_KEY` | - | Required for OpenAI provider |
|
|
183
|
+
| `TOOL_RESULT_FORMAT` | `result` | `result`, `function_result`, or `function_args_result` |
|
|
184
|
+
| `MCP_TOOL_CACHE_TTL` | `30` | Tool cache TTL in seconds (0 = indefinite) |
|
|
185
|
+
| `LOG_LEVEL` | `INFO` | Logging level |
|
|
186
|
+
|
|
187
|
+
## Troubleshooting
|
|
188
|
+
|
|
189
|
+
Common issues and solutions are covered in the [Troubleshooting Guide](docs/troubleshooting.md).
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
[MIT License](LICENSE)
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
casual_mcp/__init__.py,sha256=eeI1TIj8Cu-H4OMV64LaNqVqo4wSFaGu7215hJeN_HM,598
|
|
2
|
-
casual_mcp/cli.py,sha256=
|
|
2
|
+
casual_mcp/cli.py,sha256=yzNkS2rZ8Lb-1nGFY75RUaixHf1x-vf6gdUPU58jOlg,14953
|
|
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=OxW6itdauq23QyxPhCt6K0kM2jV2WlP_JSfk5IKSN48,6057
|
|
6
|
+
casual_mcp/mcp_tool_chat.py,sha256=h9-1wzgLIhm6kfaNHNJ3RGwkL3A3Q3EoUZvnxIroL74,11144
|
|
7
7
|
casual_mcp/provider_factory.py,sha256=Jp2HQOJdlDDed-hfZf1drEVbw0kpZSE0TN9G0Dcp4w8,1260
|
|
8
8
|
casual_mcp/tool_cache.py,sha256=VE599sF7vHH6megcueqVxCZavvTcoFDoZu2QuZM3cYA,3161
|
|
9
|
+
casual_mcp/tool_filter.py,sha256=u1C8w0CNZ4AH4bbkIRz0ph9-g9-OxSBnkZiLJVapyHo,5430
|
|
9
10
|
casual_mcp/utils.py,sha256=XxzPxQ3j97edeCRXtoO8lJS9R0JYOa25p2MJNwGapJA,3201
|
|
10
|
-
casual_mcp/models/__init__.py,sha256=
|
|
11
|
+
casual_mcp/models/__init__.py,sha256=2D3grALibdsymdpI82EHVGCgEKCszU418qh61os7_rM,924
|
|
11
12
|
casual_mcp/models/chat_stats.py,sha256=ZjeZ_ckx-SfioYs39NAaQxK6qPG9SlFlrB7j7jHZ40w,1221
|
|
12
|
-
casual_mcp/models/config.py,sha256=
|
|
13
|
+
casual_mcp/models/config.py,sha256=JsgRtZzA3jZALfAKj-nMIJjnd4RmGmJsLUdzQ_6wCZk,436
|
|
13
14
|
casual_mcp/models/generation_error.py,sha256=abDAahS2fhYkS-ARng1Tk7oudoAO4imkoKYcC9PHT2U,272
|
|
14
15
|
casual_mcp/models/mcp_server_config.py,sha256=0OHsHUEKxRoCl21lsye4E5GoCNmdZWIZCOOthcTpdsE,539
|
|
15
16
|
casual_mcp/models/model_config.py,sha256=59Y7MvcboPKdAilSwUyeC7lfRm4aYkFhZ5c8EVRP5ys,425
|
|
16
|
-
casual_mcp
|
|
17
|
-
casual_mcp-0.
|
|
18
|
-
casual_mcp-0.
|
|
19
|
-
casual_mcp-0.
|
|
20
|
-
casual_mcp-0.
|
|
21
|
-
casual_mcp-0.
|
|
17
|
+
casual_mcp/models/toolset_config.py,sha256=k95TqhHXYDonAt0GG5akzZRWzQ6rZG77eLB7QlSV5AA,1246
|
|
18
|
+
casual_mcp-0.7.0.dist-info/licenses/LICENSE,sha256=U3Zu2tkrh5vXdy7gIdE8WJGM9D4gGp3hohAAWdre-yo,1058
|
|
19
|
+
casual_mcp-0.7.0.dist-info/METADATA,sha256=8S2ssCaPlmVS3zYobzuzRKsLSyyKP_QHzjRCAtfdP80,6211
|
|
20
|
+
casual_mcp-0.7.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
21
|
+
casual_mcp-0.7.0.dist-info/entry_points.txt,sha256=X48Np2cwl-SlRQdV26y2vPZ-2tJaODgZeVtfpHho-zg,50
|
|
22
|
+
casual_mcp-0.7.0.dist-info/top_level.txt,sha256=K4CiI0Jf8PHICjuQVm32HuNMB44kp8Lb02bbbdiH5bo,11
|
|
23
|
+
casual_mcp-0.7.0.dist-info/RECORD,,
|