hvtracker-mcp 0.1.0__tar.gz

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.
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 YugantM
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,132 @@
1
+ Metadata-Version: 2.4
2
+ Name: hvtracker-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for HVTracker trust checks.
5
+ Author: YugantM
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://hvtracker.net
8
+ Project-URL: Repository, https://github.com/YugantM/hvtracker-mcp
9
+ Project-URL: Issues, https://github.com/YugantM/hvtracker-mcp/issues
10
+ Keywords: mcp,model-context-protocol,ai-agents,trust,supply-chain
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Security
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: mcp>=1.27.2
23
+ Requires-Dist: requests>=2.32.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: build>=1.2.0; extra == "dev"
26
+ Requires-Dist: pytest>=9.0.0; extra == "dev"
27
+ Requires-Dist: ruff>=0.15.0; extra == "dev"
28
+ Requires-Dist: twine>=6.0.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # HVTracker MCP
32
+
33
+ MCP server for checking supply-chain trust before connecting to AI agents,
34
+ frameworks, or MCP servers.
35
+
36
+ The hosted remote server is:
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "hvtracker": {
42
+ "url": "https://hvtracker.net/mcp"
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ This repository also provides a local stdio package for clients that prefer
49
+ package-based installation.
50
+
51
+ <!-- mcp-name: io.github.yugantm/hvtracker-mcp -->
52
+
53
+ ## Tools
54
+
55
+ - `verify_mcp_server`: pre-connect trust verdict for an MCP server, package, GitHub repo, or agent name.
56
+ - `check_agent_trust`: compact trust profile for a tracked AI agent or framework.
57
+ - `search_agents`: search the HVTracker registry by name, repo, description, or category.
58
+
59
+ ## Local Install
60
+
61
+ With npm:
62
+
63
+ ```bash
64
+ npm install -g hvtracker-mcp
65
+ ```
66
+
67
+ With PyPI:
68
+
69
+ ```bash
70
+ python3 -m pip install hvtracker-mcp
71
+ ```
72
+
73
+ Example MCP client config:
74
+
75
+ ```json
76
+ {
77
+ "mcpServers": {
78
+ "hvtracker": {
79
+ "command": "hvtracker-mcp"
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ ## Development
86
+
87
+ ```bash
88
+ python3 -m pip install -e ".[dev]"
89
+ python3 -m pytest
90
+ hvtracker-mcp
91
+ ```
92
+
93
+ Use a different HVTracker base URL while testing:
94
+
95
+ ```bash
96
+ HVTRACKER_BASE_URL=http://localhost:8080 hvtracker-mcp
97
+ ```
98
+
99
+ ## Registry Publishing
100
+
101
+ The official MCP Registry manifest is `server.json`.
102
+
103
+ ```bash
104
+ mcp-publisher login github
105
+ mcp-publisher publish
106
+ ```
107
+
108
+ In GitHub Actions, run the "Publish MCP Registry" workflow after the npm,
109
+ PyPI, and GHCR packages for the same version are live.
110
+
111
+ The server name is:
112
+
113
+ ```text
114
+ io.github.yugantm/hvtracker-mcp
115
+ ```
116
+
117
+ ## Claude Desktop Extension
118
+
119
+ Tagged releases build an `.mcpb` bundle for Claude Desktop from `manifest.json`.
120
+ To build it locally:
121
+
122
+ ```bash
123
+ npm ci --omit=dev
124
+ npx @anthropic-ai/mcpb@2.1.2 pack
125
+ ```
126
+
127
+ ## Privacy
128
+
129
+ HVTracker MCP sends the user-supplied search string or server identifier to
130
+ `https://hvtracker.net` to fetch public trust data. It does not require an API
131
+ key and does not write to user systems. See the HVTracker site for current data
132
+ and methodology, and see `PRIVACY.md` for the repository privacy note.
@@ -0,0 +1,102 @@
1
+ # HVTracker MCP
2
+
3
+ MCP server for checking supply-chain trust before connecting to AI agents,
4
+ frameworks, or MCP servers.
5
+
6
+ The hosted remote server is:
7
+
8
+ ```json
9
+ {
10
+ "mcpServers": {
11
+ "hvtracker": {
12
+ "url": "https://hvtracker.net/mcp"
13
+ }
14
+ }
15
+ }
16
+ ```
17
+
18
+ This repository also provides a local stdio package for clients that prefer
19
+ package-based installation.
20
+
21
+ <!-- mcp-name: io.github.yugantm/hvtracker-mcp -->
22
+
23
+ ## Tools
24
+
25
+ - `verify_mcp_server`: pre-connect trust verdict for an MCP server, package, GitHub repo, or agent name.
26
+ - `check_agent_trust`: compact trust profile for a tracked AI agent or framework.
27
+ - `search_agents`: search the HVTracker registry by name, repo, description, or category.
28
+
29
+ ## Local Install
30
+
31
+ With npm:
32
+
33
+ ```bash
34
+ npm install -g hvtracker-mcp
35
+ ```
36
+
37
+ With PyPI:
38
+
39
+ ```bash
40
+ python3 -m pip install hvtracker-mcp
41
+ ```
42
+
43
+ Example MCP client config:
44
+
45
+ ```json
46
+ {
47
+ "mcpServers": {
48
+ "hvtracker": {
49
+ "command": "hvtracker-mcp"
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ ## Development
56
+
57
+ ```bash
58
+ python3 -m pip install -e ".[dev]"
59
+ python3 -m pytest
60
+ hvtracker-mcp
61
+ ```
62
+
63
+ Use a different HVTracker base URL while testing:
64
+
65
+ ```bash
66
+ HVTRACKER_BASE_URL=http://localhost:8080 hvtracker-mcp
67
+ ```
68
+
69
+ ## Registry Publishing
70
+
71
+ The official MCP Registry manifest is `server.json`.
72
+
73
+ ```bash
74
+ mcp-publisher login github
75
+ mcp-publisher publish
76
+ ```
77
+
78
+ In GitHub Actions, run the "Publish MCP Registry" workflow after the npm,
79
+ PyPI, and GHCR packages for the same version are live.
80
+
81
+ The server name is:
82
+
83
+ ```text
84
+ io.github.yugantm/hvtracker-mcp
85
+ ```
86
+
87
+ ## Claude Desktop Extension
88
+
89
+ Tagged releases build an `.mcpb` bundle for Claude Desktop from `manifest.json`.
90
+ To build it locally:
91
+
92
+ ```bash
93
+ npm ci --omit=dev
94
+ npx @anthropic-ai/mcpb@2.1.2 pack
95
+ ```
96
+
97
+ ## Privacy
98
+
99
+ HVTracker MCP sends the user-supplied search string or server identifier to
100
+ `https://hvtracker.net` to fetch public trust data. It does not require an API
101
+ key and does not write to user systems. See the HVTracker site for current data
102
+ and methodology, and see `PRIVACY.md` for the repository privacy note.
@@ -0,0 +1,54 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "hvtracker-mcp"
7
+ version = "0.1.0"
8
+ description = "MCP server for HVTracker trust checks."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "YugantM" }
14
+ ]
15
+ keywords = ["mcp", "model-context-protocol", "ai-agents", "trust", "supply-chain"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Topic :: Security",
24
+ "Topic :: Software Development :: Libraries :: Python Modules"
25
+ ]
26
+ dependencies = [
27
+ "mcp>=1.27.2",
28
+ "requests>=2.32.0"
29
+ ]
30
+
31
+ [project.optional-dependencies]
32
+ dev = [
33
+ "build>=1.2.0",
34
+ "pytest>=9.0.0",
35
+ "ruff>=0.15.0",
36
+ "twine>=6.0.0"
37
+ ]
38
+
39
+ [project.scripts]
40
+ hvtracker-mcp = "hvtracker_mcp.server:main"
41
+
42
+ [project.urls]
43
+ Homepage = "https://hvtracker.net"
44
+ Repository = "https://github.com/YugantM/hvtracker-mcp"
45
+ Issues = "https://github.com/YugantM/hvtracker-mcp/issues"
46
+
47
+ [tool.setuptools.packages.find]
48
+ where = ["src"]
49
+
50
+ [tool.ruff]
51
+ line-length = 100
52
+
53
+ [tool.pytest.ini_options]
54
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ """HVTracker MCP package."""
2
+
3
+ __version__ = "0.1.0"
4
+
@@ -0,0 +1,6 @@
1
+ from .server import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ main()
6
+
@@ -0,0 +1,150 @@
1
+ """Standalone HVTracker MCP server.
2
+
3
+ The hosted production endpoint is https://hvtracker.net/mcp. This package is
4
+ the local stdio distribution path: it exposes the same user-facing tools and
5
+ delegates verdicts/searches to HVTracker's public HTTPS API.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import argparse
11
+ import os
12
+ from typing import Any
13
+
14
+ import requests
15
+ from mcp.server.fastmcp import FastMCP
16
+ from mcp.types import ToolAnnotations
17
+
18
+ from . import __version__
19
+
20
+ DEFAULT_BASE_URL = "https://hvtracker.net"
21
+ BASE_URL = os.environ.get("HVTRACKER_BASE_URL", DEFAULT_BASE_URL).rstrip("/")
22
+ TIMEOUT_SECONDS = float(os.environ.get("HVTRACKER_TIMEOUT_SECONDS", "20"))
23
+
24
+ mcp = FastMCP("hvtracker", instructions="Check trust signals for AI agents and MCP servers.")
25
+ READ_ONLY = ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=True)
26
+
27
+
28
+ def _api_get(path: str, params: dict[str, Any] | None = None) -> dict[str, Any]:
29
+ url = f"{BASE_URL}{path}"
30
+ response = requests.get(
31
+ url,
32
+ params=params,
33
+ timeout=TIMEOUT_SECONDS,
34
+ headers={"User-Agent": f"hvtracker-mcp/{__version__}"},
35
+ )
36
+ response.raise_for_status()
37
+ payload = response.json()
38
+ if not isinstance(payload, dict):
39
+ raise ValueError(f"Unexpected response shape from {url}")
40
+ return payload
41
+
42
+
43
+ def _agent_profile(agent: dict[str, Any]) -> dict[str, Any]:
44
+ slug = agent.get("slug")
45
+ return {
46
+ "tracked": True,
47
+ "name": agent.get("name"),
48
+ "repo": agent.get("repo"),
49
+ "trust_score": agent.get("trust_score"),
50
+ "evidence_grade": agent.get("evidence_grade"),
51
+ "rank": agent.get("rank"),
52
+ "category": agent.get("category"),
53
+ "has_provenance": agent.get("has_provenance"),
54
+ "scorecard_score": agent.get("scorecard_score"),
55
+ "mcp_server_support": (agent.get("mcp_server_support") or {}).get("status"),
56
+ "profile_url": f"{BASE_URL}/agents/{slug}/" if slug else None,
57
+ }
58
+
59
+
60
+ @mcp.tool(title="Verify MCP Server", annotations=READ_ONLY)
61
+ def verify_mcp_server(server: str) -> dict[str, Any]:
62
+ """Pre-connect trust verdict for an MCP server or AI agent.
63
+
64
+ Pass a GitHub owner/repo, GitHub URL, npm/PyPI package, display name, slug,
65
+ or MCP server URL. Unknown servers return trusted=false because HVTracker has
66
+ no independent evidence, not because harm is proven.
67
+ """
68
+ try:
69
+ return _api_get("/api/v1/mcp/verify", {"server": server})
70
+ except Exception as exc:
71
+ return {
72
+ "server": server,
73
+ "tracked": False,
74
+ "trusted": False,
75
+ "error": str(exc),
76
+ "reasons": ["HVTracker could not fetch a verdict right now."],
77
+ }
78
+
79
+
80
+ @mcp.tool(title="Check Agent Trust", annotations=READ_ONLY)
81
+ def check_agent_trust(name_or_repo: str) -> dict[str, Any]:
82
+ """Get the HVTracker trust profile for a tracked AI agent or framework."""
83
+ verdict = verify_mcp_server(name_or_repo)
84
+ if not verdict.get("tracked"):
85
+ return {
86
+ "query": name_or_repo,
87
+ "tracked": False,
88
+ "trusted": False,
89
+ "message": "Not in the HVTracker registry; treat as unverified.",
90
+ "submit_url": f"{BASE_URL}/submit",
91
+ "verdict": verdict,
92
+ }
93
+ slug = verdict.get("slug")
94
+ return {
95
+ "query": name_or_repo,
96
+ "tracked": True,
97
+ "trusted": verdict.get("trusted"),
98
+ "repo": verdict.get("resolved"),
99
+ "slug": slug,
100
+ "trust_score": verdict.get("trust_score"),
101
+ "evidence_grade": verdict.get("grade"),
102
+ "confidence": verdict.get("confidence"),
103
+ "mcp_server_support": verdict.get("mcp_server_support"),
104
+ "tool_permissions": verdict.get("tool_permissions") or [],
105
+ "profile_url": f"{BASE_URL}/agents/{slug}/" if slug else None,
106
+ "reasons": verdict.get("reasons") or [],
107
+ }
108
+
109
+
110
+ @mcp.tool(title="Search Agents", annotations=READ_ONLY)
111
+ def search_agents(query: str = "", category: str = "", limit: int = 10) -> dict[str, Any]:
112
+ """Search tracked AI agents and frameworks by name, repo, or description."""
113
+ try:
114
+ data = _api_get("/api/v1/agents")
115
+ except Exception as exc:
116
+ return {"count": 0, "results": [], "error": str(exc)}
117
+
118
+ ql = (query or "").strip().lower()
119
+ cl = (category or "").strip().lower()
120
+ matches = []
121
+ for agent in data.get("agents", []):
122
+ haystack = " ".join(
123
+ str(agent.get(key) or "") for key in ("name", "repo", "description", "slug")
124
+ ).lower()
125
+ if ql and ql not in haystack:
126
+ continue
127
+ if cl and (agent.get("category") or "").lower() != cl:
128
+ continue
129
+ matches.append(_agent_profile(agent))
130
+
131
+ matches.sort(key=lambda row: (row["trust_score"] is None, -(row["trust_score"] or 0)))
132
+ limit = max(1, min(int(limit or 10), 50))
133
+ return {"count": len(matches), "results": matches[:limit]}
134
+
135
+
136
+ def main(argv: list[str] | None = None) -> None:
137
+ parser = argparse.ArgumentParser(description="Run the HVTracker MCP server.")
138
+ parser.add_argument(
139
+ "--transport",
140
+ choices=["stdio", "streamable-http"],
141
+ default=os.environ.get("HVTRACKER_MCP_TRANSPORT", "stdio"),
142
+ help="Transport to run. Use stdio for local MCP clients.",
143
+ )
144
+ args = parser.parse_args(argv)
145
+ mcp.run(transport=args.transport)
146
+
147
+
148
+ if __name__ == "__main__":
149
+ main()
150
+
@@ -0,0 +1,132 @@
1
+ Metadata-Version: 2.4
2
+ Name: hvtracker-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for HVTracker trust checks.
5
+ Author: YugantM
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://hvtracker.net
8
+ Project-URL: Repository, https://github.com/YugantM/hvtracker-mcp
9
+ Project-URL: Issues, https://github.com/YugantM/hvtracker-mcp/issues
10
+ Keywords: mcp,model-context-protocol,ai-agents,trust,supply-chain
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Security
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: mcp>=1.27.2
23
+ Requires-Dist: requests>=2.32.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: build>=1.2.0; extra == "dev"
26
+ Requires-Dist: pytest>=9.0.0; extra == "dev"
27
+ Requires-Dist: ruff>=0.15.0; extra == "dev"
28
+ Requires-Dist: twine>=6.0.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # HVTracker MCP
32
+
33
+ MCP server for checking supply-chain trust before connecting to AI agents,
34
+ frameworks, or MCP servers.
35
+
36
+ The hosted remote server is:
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "hvtracker": {
42
+ "url": "https://hvtracker.net/mcp"
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ This repository also provides a local stdio package for clients that prefer
49
+ package-based installation.
50
+
51
+ <!-- mcp-name: io.github.yugantm/hvtracker-mcp -->
52
+
53
+ ## Tools
54
+
55
+ - `verify_mcp_server`: pre-connect trust verdict for an MCP server, package, GitHub repo, or agent name.
56
+ - `check_agent_trust`: compact trust profile for a tracked AI agent or framework.
57
+ - `search_agents`: search the HVTracker registry by name, repo, description, or category.
58
+
59
+ ## Local Install
60
+
61
+ With npm:
62
+
63
+ ```bash
64
+ npm install -g hvtracker-mcp
65
+ ```
66
+
67
+ With PyPI:
68
+
69
+ ```bash
70
+ python3 -m pip install hvtracker-mcp
71
+ ```
72
+
73
+ Example MCP client config:
74
+
75
+ ```json
76
+ {
77
+ "mcpServers": {
78
+ "hvtracker": {
79
+ "command": "hvtracker-mcp"
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ ## Development
86
+
87
+ ```bash
88
+ python3 -m pip install -e ".[dev]"
89
+ python3 -m pytest
90
+ hvtracker-mcp
91
+ ```
92
+
93
+ Use a different HVTracker base URL while testing:
94
+
95
+ ```bash
96
+ HVTRACKER_BASE_URL=http://localhost:8080 hvtracker-mcp
97
+ ```
98
+
99
+ ## Registry Publishing
100
+
101
+ The official MCP Registry manifest is `server.json`.
102
+
103
+ ```bash
104
+ mcp-publisher login github
105
+ mcp-publisher publish
106
+ ```
107
+
108
+ In GitHub Actions, run the "Publish MCP Registry" workflow after the npm,
109
+ PyPI, and GHCR packages for the same version are live.
110
+
111
+ The server name is:
112
+
113
+ ```text
114
+ io.github.yugantm/hvtracker-mcp
115
+ ```
116
+
117
+ ## Claude Desktop Extension
118
+
119
+ Tagged releases build an `.mcpb` bundle for Claude Desktop from `manifest.json`.
120
+ To build it locally:
121
+
122
+ ```bash
123
+ npm ci --omit=dev
124
+ npx @anthropic-ai/mcpb@2.1.2 pack
125
+ ```
126
+
127
+ ## Privacy
128
+
129
+ HVTracker MCP sends the user-supplied search string or server identifier to
130
+ `https://hvtracker.net` to fetch public trust data. It does not require an API
131
+ key and does not write to user systems. See the HVTracker site for current data
132
+ and methodology, and see `PRIVACY.md` for the repository privacy note.
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/hvtracker_mcp/__init__.py
5
+ src/hvtracker_mcp/__main__.py
6
+ src/hvtracker_mcp/server.py
7
+ src/hvtracker_mcp.egg-info/PKG-INFO
8
+ src/hvtracker_mcp.egg-info/SOURCES.txt
9
+ src/hvtracker_mcp.egg-info/dependency_links.txt
10
+ src/hvtracker_mcp.egg-info/entry_points.txt
11
+ src/hvtracker_mcp.egg-info/requires.txt
12
+ src/hvtracker_mcp.egg-info/top_level.txt
13
+ tests/test_server.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ hvtracker-mcp = hvtracker_mcp.server:main
@@ -0,0 +1,8 @@
1
+ mcp>=1.27.2
2
+ requests>=2.32.0
3
+
4
+ [dev]
5
+ build>=1.2.0
6
+ pytest>=9.0.0
7
+ ruff>=0.15.0
8
+ twine>=6.0.0
@@ -0,0 +1 @@
1
+ hvtracker_mcp
@@ -0,0 +1,74 @@
1
+ import asyncio
2
+
3
+ from hvtracker_mcp import server
4
+
5
+
6
+ def test_verify_mcp_server_delegates_to_api(monkeypatch):
7
+ def fake_get(path, params=None):
8
+ assert path == "/api/v1/mcp/verify"
9
+ assert params == {"server": "langchain-ai/langgraph"}
10
+ return {"tracked": True, "trusted": True, "resolved": "langchain-ai/langgraph"}
11
+
12
+ monkeypatch.setattr(server, "_api_get", fake_get)
13
+ assert server.verify_mcp_server("langchain-ai/langgraph")["trusted"] is True
14
+
15
+
16
+ def test_check_agent_trust_maps_verdict(monkeypatch):
17
+ monkeypatch.setattr(
18
+ server,
19
+ "verify_mcp_server",
20
+ lambda query: {
21
+ "tracked": True,
22
+ "trusted": True,
23
+ "resolved": "langchain-ai/langgraph",
24
+ "slug": "langgraph",
25
+ "trust_score": 92.8,
26
+ "grade": "A",
27
+ "confidence": 1.0,
28
+ "mcp_server_support": "none",
29
+ "tool_permissions": ["code"],
30
+ "reasons": ["Build provenance present."],
31
+ },
32
+ )
33
+ result = server.check_agent_trust("LangGraph")
34
+ assert result["repo"] == "langchain-ai/langgraph"
35
+ assert result["profile_url"].endswith("/agents/langgraph/")
36
+
37
+
38
+ def test_search_agents_filters_and_sorts(monkeypatch):
39
+ monkeypatch.setattr(
40
+ server,
41
+ "_api_get",
42
+ lambda path: {
43
+ "agents": [
44
+ {
45
+ "name": "Lower",
46
+ "repo": "example/lower",
47
+ "slug": "lower",
48
+ "trust_score": 40,
49
+ "evidence_grade": "C",
50
+ "category": "Coding Agents",
51
+ "description": "agent",
52
+ },
53
+ {
54
+ "name": "Higher",
55
+ "repo": "example/higher",
56
+ "slug": "higher",
57
+ "trust_score": 90,
58
+ "evidence_grade": "A",
59
+ "category": "Coding Agents",
60
+ "description": "agent",
61
+ },
62
+ ]
63
+ },
64
+ )
65
+ result = server.search_agents(query="example", category="Coding Agents")
66
+ assert result["count"] == 2
67
+ assert [row["name"] for row in result["results"]] == ["Higher", "Lower"]
68
+
69
+
70
+ def test_tools_have_read_only_annotations():
71
+ tools = {tool.name: tool for tool in asyncio.run(server.mcp.list_tools())}
72
+ assert set(tools) == {"verify_mcp_server", "check_agent_trust", "search_agents"}
73
+ assert tools["verify_mcp_server"].annotations.readOnlyHint is True
74
+