intermcp 0.2.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.
- intermcp/__init__.py +9 -0
- intermcp/client.py +137 -0
- intermcp-0.2.0.dist-info/METADATA +40 -0
- intermcp-0.2.0.dist-info/RECORD +6 -0
- intermcp-0.2.0.dist-info/WHEEL +5 -0
- intermcp-0.2.0.dist-info/top_level.txt +1 -0
intermcp/__init__.py
ADDED
intermcp/client.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""
|
|
2
|
+
InterMCP Python Client
|
|
3
|
+
High-Performance Model Context Protocol Client for Python AI Agents.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
import threading
|
|
11
|
+
from typing import Any, Dict, List, Optional
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class InterMcpClient:
|
|
15
|
+
"""Python client for connecting to the native InterMCP Trust Runtime."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, binary_path: Optional[str] = None):
|
|
18
|
+
if binary_path is None:
|
|
19
|
+
is_win = sys.platform == "win32"
|
|
20
|
+
exe_name = "intermcp.exe" if is_win else "intermcp"
|
|
21
|
+
candidates = [
|
|
22
|
+
os.environ.get("INTERMCP_BIN"),
|
|
23
|
+
os.path.join(os.path.expanduser("~"), ".intermcp", "bin", exe_name),
|
|
24
|
+
os.path.join(os.path.dirname(__file__), "..", "..", "target", "release", exe_name),
|
|
25
|
+
exe_name,
|
|
26
|
+
]
|
|
27
|
+
self.binary_path = next((p for p in candidates if p and os.path.exists(p)), exe_name)
|
|
28
|
+
else:
|
|
29
|
+
self.binary_path = binary_path
|
|
30
|
+
|
|
31
|
+
self.proc: Optional[subprocess.Popen] = None
|
|
32
|
+
self.request_id = 0
|
|
33
|
+
self._lock = threading.Lock()
|
|
34
|
+
|
|
35
|
+
def start(self) -> Dict[str, Any]:
|
|
36
|
+
"""Start the native InterMCP process and perform MCP 2024-11-05 handshake."""
|
|
37
|
+
self.proc = subprocess.Popen(
|
|
38
|
+
[self.binary_path, "serve"],
|
|
39
|
+
stdin=subprocess.PIPE,
|
|
40
|
+
stdout=subprocess.PIPE,
|
|
41
|
+
stderr=subprocess.PIPE,
|
|
42
|
+
text=True,
|
|
43
|
+
bufsize=1,
|
|
44
|
+
encoding="utf-8",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
return self.request("initialize", {
|
|
48
|
+
"protocolVersion": "2024-11-05",
|
|
49
|
+
"clientInfo": {"name": "intermcp-python-sdk", "version": "0.2.0"},
|
|
50
|
+
"capabilities": {}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
def request(self, method: str, params: Optional[Dict[str, Any]] = None) -> Any:
|
|
54
|
+
"""Send a standard JSON-RPC 2.0 message and return result.
|
|
55
|
+
|
|
56
|
+
Note on Threading / Concurrency (Finding 17):
|
|
57
|
+
Stdio-based JSON-RPC requires strict serial request-response framing across
|
|
58
|
+
standard input/output pipes. `self._lock` serializes requests across multiple threads
|
|
59
|
+
to prevent interleaving. For high-concurrency async workloads, use the async client
|
|
60
|
+
or HTTP/SSE transport.
|
|
61
|
+
"""
|
|
62
|
+
with self._lock:
|
|
63
|
+
if not self.proc or not self.proc.stdin or not self.proc.stdout:
|
|
64
|
+
raise RuntimeError("InterMCP client is not running. Call .start() first.")
|
|
65
|
+
|
|
66
|
+
self.request_id += 1
|
|
67
|
+
msg = json.dumps({
|
|
68
|
+
"jsonrpc": "2.0",
|
|
69
|
+
"id": self.request_id,
|
|
70
|
+
"method": method,
|
|
71
|
+
"params": params or {},
|
|
72
|
+
}) + "\n"
|
|
73
|
+
|
|
74
|
+
self.proc.stdin.write(msg)
|
|
75
|
+
self.proc.stdin.flush()
|
|
76
|
+
|
|
77
|
+
line = self.proc.stdout.readline()
|
|
78
|
+
if not line:
|
|
79
|
+
err = self.proc.stderr.read() if self.proc.stderr else "Unknown error"
|
|
80
|
+
raise RuntimeError(f"InterMCP engine process exited: {err}")
|
|
81
|
+
|
|
82
|
+
payload = json.loads(line)
|
|
83
|
+
if "error" in payload:
|
|
84
|
+
raise RuntimeError(f"MCP Error {payload['error'].get('code')}: {payload['error'].get('message')}")
|
|
85
|
+
|
|
86
|
+
return payload.get("result")
|
|
87
|
+
|
|
88
|
+
def list_tools(self) -> List[Dict[str, Any]]:
|
|
89
|
+
"""List all registered tools."""
|
|
90
|
+
res = self.request("tools/list")
|
|
91
|
+
return res.get("tools", [])
|
|
92
|
+
|
|
93
|
+
def call_tool(self, name: str, arguments: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
|
94
|
+
"""Execute a tool with SafeFS, secret redaction, and signed receipts."""
|
|
95
|
+
return self.request("tools/call", {
|
|
96
|
+
"name": name,
|
|
97
|
+
"arguments": arguments or {}
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
def list_resources(self) -> List[Dict[str, Any]]:
|
|
101
|
+
"""List all resources."""
|
|
102
|
+
res = self.request("resources/list")
|
|
103
|
+
return res.get("resources", [])
|
|
104
|
+
|
|
105
|
+
def read_resource(self, uri: str) -> Dict[str, Any]:
|
|
106
|
+
"""Read resource content."""
|
|
107
|
+
return self.request("resources/read", {"uri": uri})
|
|
108
|
+
|
|
109
|
+
def list_prompts(self) -> List[Dict[str, Any]]:
|
|
110
|
+
"""List reusable prompt templates."""
|
|
111
|
+
res = self.request("prompts/list")
|
|
112
|
+
return res.get("prompts", [])
|
|
113
|
+
|
|
114
|
+
def get_prompt(self, name: str, arguments: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
|
115
|
+
"""Retrieve a specific prompt."""
|
|
116
|
+
return self.request("prompts/get", {
|
|
117
|
+
"name": name,
|
|
118
|
+
"arguments": arguments or {}
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
def stop(self):
|
|
122
|
+
"""Cleanly terminate the native runtime."""
|
|
123
|
+
with self._lock:
|
|
124
|
+
if self.proc:
|
|
125
|
+
try:
|
|
126
|
+
self.proc.terminate()
|
|
127
|
+
self.proc.wait(timeout=2)
|
|
128
|
+
except Exception:
|
|
129
|
+
self.proc.kill()
|
|
130
|
+
self.proc = None
|
|
131
|
+
|
|
132
|
+
def __enter__(self):
|
|
133
|
+
self.start()
|
|
134
|
+
return self
|
|
135
|
+
|
|
136
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
137
|
+
self.stop()
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: intermcp
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Ultra-Fast, Safe Model Context Protocol (MCP) Python Client for InterMCP Trust Runtime
|
|
5
|
+
Author-email: Bharath B R <bharathcoorg7@gmail.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/Bharathcoorg/intermcp
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/Bharathcoorg/intermcp/issues
|
|
8
|
+
Keywords: mcp,model-context-protocol,ai,claude,cursor,agents,interlayer
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
|
+
Requires-Python: >=3.8
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# InterMCP Python Client
|
|
18
|
+
|
|
19
|
+
Official Python Client for **InterMCP** — Ultra-Fast, Safe Model Context Protocol (MCP) Runtime.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install intermcp
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quickstart
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from intermcp import InterMcpClient
|
|
31
|
+
|
|
32
|
+
with InterMcpClient() as client:
|
|
33
|
+
# Query registered tools
|
|
34
|
+
tools = client.list_tools()
|
|
35
|
+
print("Available tools:", [t["name"] for t in tools])
|
|
36
|
+
|
|
37
|
+
# Call a tool with sub-microsecond latency
|
|
38
|
+
info = client.call_tool("system_info", {})
|
|
39
|
+
print(info)
|
|
40
|
+
```
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
intermcp/__init__.py,sha256=gbJIxJewZIF7rsbM7FMuUl_e_wMlatgyYq1DrlrGu5g,170
|
|
2
|
+
intermcp/client.py,sha256=8LOzQPaxS5MaY-TeQ21yxZmJ8B2FGis36b0VZHCMoSc,4913
|
|
3
|
+
intermcp-0.2.0.dist-info/METADATA,sha256=3eTduU1MwsEN2eydF3JaZUZVME3UL_Bz_tO-yKVQXWw,1270
|
|
4
|
+
intermcp-0.2.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
5
|
+
intermcp-0.2.0.dist-info/top_level.txt,sha256=pTCNbqSd2xja5JAPUWxlB7M5qRvGxD-BfrdRcYCk9hI,9
|
|
6
|
+
intermcp-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
intermcp
|