windsock-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,71 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: windsock-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Windsock aircraft intelligence for AI agents: stdio bridge and client helper for the Windsock MCP server (valuations, FAA registry, cost of ownership, market data, reports, logbooks).
|
|
5
|
+
Project-URL: Homepage, https://windsock.ai/mcp
|
|
6
|
+
Project-URL: Documentation, https://windsock.ai/mcp
|
|
7
|
+
Project-URL: Support, https://windsock.ai/contact
|
|
8
|
+
Author-email: Windsock <team@windsock.ai>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: agents,aircraft,aviation,faa,mcp,model-context-protocol,registry,valuation,windsock
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: anyio>=4
|
|
18
|
+
Requires-Dist: httpx>=0.27
|
|
19
|
+
Requires-Dist: mcp>=1.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# windsock-mcp
|
|
23
|
+
|
|
24
|
+
Windsock aircraft intelligence for AI agents, from Python.
|
|
25
|
+
|
|
26
|
+
[Windsock](https://windsock.ai) exposes 38 tools over the Model Context Protocol
|
|
27
|
+
at `https://windsock.ai/mcp`: aircraft valuations, FAA registry lookups, cost of
|
|
28
|
+
ownership, comparable aircraft, fleet search, ADs and STCs, market metrics with
|
|
29
|
+
forecasts, verified value reports, pre-buy diligence checklists, logbook search
|
|
30
|
+
and a watchlist. This package gives you a client helper and a stdio bridge.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install windsock-mcp
|
|
34
|
+
export WINDSOCK_API_KEY=wsk_… # Integrations → Agents & SDKs in your Windsock account
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Call tools directly
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
import asyncio
|
|
41
|
+
from windsock_mcp import connect
|
|
42
|
+
|
|
43
|
+
async def main():
|
|
44
|
+
async with connect() as session:
|
|
45
|
+
tools = await session.list_tools()
|
|
46
|
+
print([t.name for t in tools.tools])
|
|
47
|
+
result = await session.call_tool("lookup_aircraft", {"registration": "N12345"})
|
|
48
|
+
print(result.content[0].text)
|
|
49
|
+
|
|
50
|
+
asyncio.run(main())
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Use as a stdio MCP server
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
"windsock": {
|
|
59
|
+
"command": "windsock-mcp",
|
|
60
|
+
"env": { "WINDSOCK_API_KEY": "wsk_…" }
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Docs
|
|
67
|
+
|
|
68
|
+
- https://windsock.ai/mcp — endpoint, auth, quickstarts, full tool catalog
|
|
69
|
+
- https://windsock.ai/mcp/llms.txt — machine-readable index
|
|
70
|
+
|
|
71
|
+
MIT © Windsock
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# windsock-mcp
|
|
2
|
+
|
|
3
|
+
Windsock aircraft intelligence for AI agents, from Python.
|
|
4
|
+
|
|
5
|
+
[Windsock](https://windsock.ai) exposes 38 tools over the Model Context Protocol
|
|
6
|
+
at `https://windsock.ai/mcp`: aircraft valuations, FAA registry lookups, cost of
|
|
7
|
+
ownership, comparable aircraft, fleet search, ADs and STCs, market metrics with
|
|
8
|
+
forecasts, verified value reports, pre-buy diligence checklists, logbook search
|
|
9
|
+
and a watchlist. This package gives you a client helper and a stdio bridge.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install windsock-mcp
|
|
13
|
+
export WINDSOCK_API_KEY=wsk_… # Integrations → Agents & SDKs in your Windsock account
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Call tools directly
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
import asyncio
|
|
20
|
+
from windsock_mcp import connect
|
|
21
|
+
|
|
22
|
+
async def main():
|
|
23
|
+
async with connect() as session:
|
|
24
|
+
tools = await session.list_tools()
|
|
25
|
+
print([t.name for t in tools.tools])
|
|
26
|
+
result = await session.call_tool("lookup_aircraft", {"registration": "N12345"})
|
|
27
|
+
print(result.content[0].text)
|
|
28
|
+
|
|
29
|
+
asyncio.run(main())
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Use as a stdio MCP server
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"mcpServers": {
|
|
37
|
+
"windsock": {
|
|
38
|
+
"command": "windsock-mcp",
|
|
39
|
+
"env": { "WINDSOCK_API_KEY": "wsk_…" }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Docs
|
|
46
|
+
|
|
47
|
+
- https://windsock.ai/mcp — endpoint, auth, quickstarts, full tool catalog
|
|
48
|
+
- https://windsock.ai/mcp/llms.txt — machine-readable index
|
|
49
|
+
|
|
50
|
+
MIT © Windsock
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "windsock-mcp"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Windsock aircraft intelligence for AI agents: stdio bridge and client helper for the Windsock MCP server (valuations, FAA registry, cost of ownership, market data, reports, logbooks)."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{ name = "Windsock", email = "team@windsock.ai" }]
|
|
13
|
+
keywords = ["mcp", "model-context-protocol", "aviation", "aircraft", "valuation", "faa", "registry", "windsock", "agents"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Software Development :: Libraries",
|
|
20
|
+
]
|
|
21
|
+
dependencies = ["mcp>=1.10", "httpx>=0.27", "anyio>=4"]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://windsock.ai/mcp"
|
|
25
|
+
Documentation = "https://windsock.ai/mcp"
|
|
26
|
+
Support = "https://windsock.ai/contact"
|
|
27
|
+
|
|
28
|
+
[project.scripts]
|
|
29
|
+
windsock-mcp = "windsock_mcp.__main__:main"
|
|
30
|
+
|
|
31
|
+
[tool.hatch.build.targets.wheel]
|
|
32
|
+
packages = ["src/windsock_mcp"]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Windsock aircraft intelligence for AI agents.
|
|
2
|
+
|
|
3
|
+
* :func:`connect` — async context manager yielding an initialized
|
|
4
|
+
:class:`mcp.ClientSession` to the remote Windsock MCP server
|
|
5
|
+
(``https://windsock.ai/mcp``), authenticated with your account API key.
|
|
6
|
+
* ``windsock-mcp`` / ``python -m windsock_mcp`` — a stdio bridge so clients that
|
|
7
|
+
only speak stdio can use the remote server.
|
|
8
|
+
|
|
9
|
+
Docs: https://windsock.ai/mcp
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import os
|
|
15
|
+
from contextlib import asynccontextmanager
|
|
16
|
+
from typing import AsyncIterator
|
|
17
|
+
|
|
18
|
+
from mcp import ClientSession
|
|
19
|
+
from mcp.client.streamable_http import create_mcp_http_client, streamable_http_client
|
|
20
|
+
|
|
21
|
+
SERVER_URL = "https://windsock.ai/mcp"
|
|
22
|
+
|
|
23
|
+
__all__ = ["SERVER_URL", "connect", "headers_for"]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def headers_for(api_key: str | None = None) -> dict[str, str]:
|
|
27
|
+
"""Bearer header for the account API key (``WINDSOCK_API_KEY`` if omitted)."""
|
|
28
|
+
key = (api_key or os.environ.get("WINDSOCK_API_KEY", "")).strip()
|
|
29
|
+
if not key:
|
|
30
|
+
raise ValueError(
|
|
31
|
+
"A Windsock API key is required: pass api_key= or set WINDSOCK_API_KEY. "
|
|
32
|
+
"Get one at https://windsock.ai/app/integrations#mcp-agents"
|
|
33
|
+
)
|
|
34
|
+
return {"Authorization": f"Bearer {key}"}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@asynccontextmanager
|
|
38
|
+
async def connect(
|
|
39
|
+
api_key: str | None = None, url: str | None = None
|
|
40
|
+
) -> AsyncIterator[ClientSession]:
|
|
41
|
+
"""Open an initialized :class:`mcp.ClientSession` to the Windsock MCP server.
|
|
42
|
+
|
|
43
|
+
Example::
|
|
44
|
+
|
|
45
|
+
async with connect() as session:
|
|
46
|
+
tools = await session.list_tools()
|
|
47
|
+
result = await session.call_tool("lookup_aircraft", {"registration": "N12345"})
|
|
48
|
+
"""
|
|
49
|
+
server_url = url or os.environ.get("WINDSOCK_MCP_URL", SERVER_URL)
|
|
50
|
+
http_client = create_mcp_http_client(headers=headers_for(api_key))
|
|
51
|
+
async with http_client:
|
|
52
|
+
async with streamable_http_client(server_url, http_client=http_client) as streams:
|
|
53
|
+
read, write = streams[0], streams[1]
|
|
54
|
+
async with ClientSession(read, write) as session:
|
|
55
|
+
await session.initialize()
|
|
56
|
+
yield session
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""``windsock-mcp`` — stdio bridge to the remote Windsock MCP server.
|
|
2
|
+
|
|
3
|
+
Forwards ``tools/list`` and ``tools/call`` from a stdio client to
|
|
4
|
+
``https://windsock.ai/mcp`` using the account API key in ``WINDSOCK_API_KEY``.
|
|
5
|
+
For interactive OAuth use prefer the npm bridge (``npx windsock-mcp``), which
|
|
6
|
+
handles the browser consent flow.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
import mcp.types as types
|
|
15
|
+
from mcp import stdio_server
|
|
16
|
+
from mcp.server import Server
|
|
17
|
+
|
|
18
|
+
from . import connect
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
async def _serve() -> None:
|
|
22
|
+
async with connect() as upstream:
|
|
23
|
+
|
|
24
|
+
async def on_list_tools(_ctx, params):
|
|
25
|
+
return await upstream.list_tools(cursor=params.cursor if params else None)
|
|
26
|
+
|
|
27
|
+
async def on_call_tool(_ctx, params: types.CallToolRequestParams):
|
|
28
|
+
return await upstream.call_tool(params.name, params.arguments or {})
|
|
29
|
+
|
|
30
|
+
server: Server = Server(
|
|
31
|
+
"windsock",
|
|
32
|
+
website_url="https://windsock.ai/mcp",
|
|
33
|
+
on_list_tools=on_list_tools,
|
|
34
|
+
on_call_tool=on_call_tool,
|
|
35
|
+
)
|
|
36
|
+
async with stdio_server() as (read, write):
|
|
37
|
+
await server.run(read, write, server.create_initialization_options())
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def main() -> None:
|
|
41
|
+
try:
|
|
42
|
+
asyncio.run(_serve())
|
|
43
|
+
except ValueError as err: # missing key
|
|
44
|
+
print(f"windsock-mcp: {err}", file=sys.stderr)
|
|
45
|
+
sys.exit(2)
|
|
46
|
+
except KeyboardInterrupt:
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
main()
|