nxtlinq-mcp-proxy 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.
Files changed (72) hide show
  1. nxtlinq_mcp_proxy-0.1.0/MANIFEST.in +8 -0
  2. nxtlinq_mcp_proxy-0.1.0/PACKAGE.md +66 -0
  3. nxtlinq_mcp_proxy-0.1.0/PKG-INFO +87 -0
  4. nxtlinq_mcp_proxy-0.1.0/README.md +74 -0
  5. nxtlinq_mcp_proxy-0.1.0/docs/assets/topology-en.svg +83 -0
  6. nxtlinq_mcp_proxy-0.1.0/docs/assets/topology-zh.svg +83 -0
  7. nxtlinq_mcp_proxy-0.1.0/docs/downloads/nxtlinq-mcp-preview.txt +3 -0
  8. nxtlinq_mcp_proxy-0.1.0/docs/en/agents.md +71 -0
  9. nxtlinq_mcp_proxy-0.1.0/docs/en/architecture.md +59 -0
  10. nxtlinq_mcp_proxy-0.1.0/docs/en/authentication.md +52 -0
  11. nxtlinq_mcp_proxy-0.1.0/docs/en/environment.md +171 -0
  12. nxtlinq_mcp_proxy-0.1.0/docs/en/examples.md +17 -0
  13. nxtlinq_mcp_proxy-0.1.0/docs/en/external-api.md +27 -0
  14. nxtlinq_mcp_proxy-0.1.0/docs/en/github-pat.md +41 -0
  15. nxtlinq_mcp_proxy-0.1.0/docs/en/host-applications.md +50 -0
  16. nxtlinq_mcp_proxy-0.1.0/docs/en/local-computation.md +29 -0
  17. nxtlinq_mcp_proxy-0.1.0/docs/en/memory.md +30 -0
  18. nxtlinq_mcp_proxy-0.1.0/docs/en/operations.md +141 -0
  19. nxtlinq_mcp_proxy-0.1.0/docs/en/packaging.md +84 -0
  20. nxtlinq_mcp_proxy-0.1.0/docs/en/quickstart.md +103 -0
  21. nxtlinq_mcp_proxy-0.1.0/docs/en/storage.md +54 -0
  22. nxtlinq_mcp_proxy-0.1.0/docs/examples/github_oauth_login.py +72 -0
  23. nxtlinq_mcp_proxy-0.1.0/docs/index.md +39 -0
  24. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/agents.md +65 -0
  25. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/architecture.md +53 -0
  26. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/authentication.md +43 -0
  27. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/environment.md +159 -0
  28. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/examples.md +15 -0
  29. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/external-api.md +24 -0
  30. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/github-pat.md +38 -0
  31. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/host-applications.md +41 -0
  32. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/local-computation.md +26 -0
  33. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/memory.md +28 -0
  34. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/operations.md +125 -0
  35. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/packaging.md +78 -0
  36. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/quickstart.md +95 -0
  37. nxtlinq_mcp_proxy-0.1.0/docs/zh-TW/storage.md +48 -0
  38. nxtlinq_mcp_proxy-0.1.0/mkdocs.yml +56 -0
  39. nxtlinq_mcp_proxy-0.1.0/pyproject.toml +29 -0
  40. nxtlinq_mcp_proxy-0.1.0/setup.cfg +4 -0
  41. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/__init__.py +2 -0
  42. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/assets/bridge.py +25 -0
  43. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/assets/login_probe.py +26 -0
  44. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/cli.py +241 -0
  45. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/codex.py +96 -0
  46. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/config.py +168 -0
  47. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/deploy.py +342 -0
  48. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/desktop.py +215 -0
  49. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/egress.py +114 -0
  50. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/oauth_callback.py +23 -0
  51. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/packaging.py +165 -0
  52. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/policy.py +71 -0
  53. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/probe.py +20 -0
  54. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/runtime.py +110 -0
  55. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/sdk_release.py +8 -0
  56. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/storage.py +130 -0
  57. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy/wizard.py +535 -0
  58. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy.egg-info/PKG-INFO +87 -0
  59. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy.egg-info/SOURCES.txt +70 -0
  60. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy.egg-info/dependency_links.txt +1 -0
  61. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy.egg-info/entry_points.txt +2 -0
  62. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy.egg-info/requires.txt +18 -0
  63. nxtlinq_mcp_proxy-0.1.0/src/nxtlinq_mcp_proxy.egg-info/top_level.txt +1 -0
  64. nxtlinq_mcp_proxy-0.1.0/tests/conftest.py +21 -0
  65. nxtlinq_mcp_proxy-0.1.0/tests/test_deployment.py +94 -0
  66. nxtlinq_mcp_proxy-0.1.0/tests/test_egress.py +137 -0
  67. nxtlinq_mcp_proxy-0.1.0/tests/test_mount_preflight.py +84 -0
  68. nxtlinq_mcp_proxy-0.1.0/tests/test_multi.py +311 -0
  69. nxtlinq_mcp_proxy-0.1.0/tests/test_packaging.py +208 -0
  70. nxtlinq_mcp_proxy-0.1.0/tests/test_policy.py +163 -0
  71. nxtlinq_mcp_proxy-0.1.0/tests/test_sdk_release.py +56 -0
  72. nxtlinq_mcp_proxy-0.1.0/tests/test_wizard.py +318 -0
@@ -0,0 +1,8 @@
1
+ recursive-include docs *.md *.svg *.py *.txt
2
+ include mkdocs.yml
3
+ include README.md PACKAGE.md
4
+ recursive-include tests *.py
5
+ prune examples
6
+ prune site
7
+ prune .nxtlinq
8
+ global-exclude *.py[cod] .DS_Store *.env .env* *.local.json .pypirc
@@ -0,0 +1,66 @@
1
+ # nxtlinq MCP Proxy
2
+
3
+ Package an existing MCP server, deploy it on a private Docker network, and
4
+ check nxtlinq tool permissions before forwarding calls. The original MCP
5
+ implements the tools. Desktop Setup manages identity and tool permissions.
6
+
7
+ ## Requirements
8
+
9
+ - uv on macOS or Linux; the guide uses uv to provide Python 3.11.
10
+ - Docker with Compose and Buildx, running on the deployment host.
11
+ - A dedicated nxtlinq thirdParty service API Key and Secret.
12
+ - An Agent supporting Streamable HTTP MCP with an Authorization header.
13
+ Automatic Codex configuration is an optional integration.
14
+
15
+ ## Install
16
+
17
+ Confirm `uv --version` works and that `docker info`,
18
+ `docker compose version`, and `docker buildx version` succeed. The source
19
+ distribution includes step-by-step environment installation guides at
20
+ `docs/en/environment.md` and `docs/zh-TW/environment.md`; skip components
21
+ that already pass these checks.
22
+
23
+ In a new working directory, create a Python virtual environment with uv, then
24
+ install the Proxy and its dependencies. uv downloads Python 3.11 if needed. For an
25
+ existing installation, activate its environment and skip environment creation.
26
+
27
+ ```sh
28
+ mkdir nxtlinq-tools
29
+ cd nxtlinq-tools
30
+ uv venv --python 3.11 .venv
31
+ source .venv/bin/activate
32
+ ```
33
+
34
+ Install from PyPI:
35
+
36
+ ```sh
37
+ uv pip install 'nxtlinq-mcp-proxy[desktop]==0.1.0'
38
+ ```
39
+
40
+ uv downloads the Proxy and its dependencies from PyPI. `[desktop]` includes Setup dependencies.
41
+
42
+ Download: [Proxy 0.1.0](https://pypi.org/project/nxtlinq-mcp-proxy/0.1.0/#files).
43
+
44
+ ## Deploy
45
+
46
+ ```sh
47
+ nxtlinq-mcp pack my-mcp-bundle
48
+ nxtlinq-mcp init my-tools --bundle my-mcp-bundle
49
+ cd my-tools
50
+ nxtlinq-mcp setup
51
+ ```
52
+
53
+ Choose the packaging method for your MCP. During initialization, select `other`
54
+ for manual MCP configuration or `codex` for the optional automatic integration.
55
+ Enter the service environment and credentials when prompted, review the discovered
56
+ tools, and confirm registration. Complete Setup and enable the tools you need,
57
+ then connect your Agent using the chosen connection option.
58
+
59
+ Use a pinned npm/Python package, a custom Dockerfile, or an existing HTTP image.
60
+ Optional recipes demonstrate Filesystem, Memory, and GitHub PAT/OAuth.
61
+ Each deployment supports up to 16 MCP servers and one user's Setup session. Configure host folders and permitted API destinations for each MCP.
62
+ The proxy governs calls through its MCP endpoint; independently accessible
63
+ files, APIs, or application endpoints require their own access controls.
64
+
65
+ English and Traditional Chinese guides are included in the source distribution
66
+ under `docs/en` and `docs/zh-TW`.
@@ -0,0 +1,87 @@
1
+ Metadata-Version: 2.4
2
+ Name: nxtlinq-mcp-proxy
3
+ Version: 0.1.0
4
+ Summary: Configure and deploy an isolated HTTP MCP behind nxtlinq authorization
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: httpx<1,>=0.27
8
+ Requires-Dist: python-dotenv<2,>=1
9
+ Provides-Extra: desktop
10
+ Requires-Dist: nxtid-sdk[desktop]==0.3.6; extra == "desktop"
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest>=8; extra == "dev"
13
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
14
+ Requires-Dist: build>=1.2; extra == "dev"
15
+ Provides-Extra: docs
16
+ Requires-Dist: mkdocs<2,>=1.6; extra == "docs"
17
+ Requires-Dist: mkdocs-material<10,>=9; extra == "docs"
18
+ Provides-Extra: release
19
+ Requires-Dist: build<2,>=1.2; extra == "release"
20
+ Requires-Dist: twine<7,>=6; extra == "release"
21
+
22
+ # nxtlinq MCP Proxy
23
+
24
+ Package an existing MCP server, deploy it on a private Docker network, and
25
+ check nxtlinq tool permissions before forwarding calls. The original MCP
26
+ implements the tools. Desktop Setup manages identity and tool permissions.
27
+
28
+ ## Requirements
29
+
30
+ - uv on macOS or Linux; the guide uses uv to provide Python 3.11.
31
+ - Docker with Compose and Buildx, running on the deployment host.
32
+ - A dedicated nxtlinq thirdParty service API Key and Secret.
33
+ - An Agent supporting Streamable HTTP MCP with an Authorization header.
34
+ Automatic Codex configuration is an optional integration.
35
+
36
+ ## Install
37
+
38
+ Confirm `uv --version` works and that `docker info`,
39
+ `docker compose version`, and `docker buildx version` succeed. The source
40
+ distribution includes step-by-step environment installation guides at
41
+ `docs/en/environment.md` and `docs/zh-TW/environment.md`; skip components
42
+ that already pass these checks.
43
+
44
+ In a new working directory, create a Python virtual environment with uv, then
45
+ install the Proxy and its dependencies. uv downloads Python 3.11 if needed. For an
46
+ existing installation, activate its environment and skip environment creation.
47
+
48
+ ```sh
49
+ mkdir nxtlinq-tools
50
+ cd nxtlinq-tools
51
+ uv venv --python 3.11 .venv
52
+ source .venv/bin/activate
53
+ ```
54
+
55
+ Install from PyPI:
56
+
57
+ ```sh
58
+ uv pip install 'nxtlinq-mcp-proxy[desktop]==0.1.0'
59
+ ```
60
+
61
+ uv downloads the Proxy and its dependencies from PyPI. `[desktop]` includes Setup dependencies.
62
+
63
+ Download: [Proxy 0.1.0](https://pypi.org/project/nxtlinq-mcp-proxy/0.1.0/#files).
64
+
65
+ ## Deploy
66
+
67
+ ```sh
68
+ nxtlinq-mcp pack my-mcp-bundle
69
+ nxtlinq-mcp init my-tools --bundle my-mcp-bundle
70
+ cd my-tools
71
+ nxtlinq-mcp setup
72
+ ```
73
+
74
+ Choose the packaging method for your MCP. During initialization, select `other`
75
+ for manual MCP configuration or `codex` for the optional automatic integration.
76
+ Enter the service environment and credentials when prompted, review the discovered
77
+ tools, and confirm registration. Complete Setup and enable the tools you need,
78
+ then connect your Agent using the chosen connection option.
79
+
80
+ Use a pinned npm/Python package, a custom Dockerfile, or an existing HTTP image.
81
+ Optional recipes demonstrate Filesystem, Memory, and GitHub PAT/OAuth.
82
+ Each deployment supports up to 16 MCP servers and one user's Setup session. Configure host folders and permitted API destinations for each MCP.
83
+ The proxy governs calls through its MCP endpoint; independently accessible
84
+ files, APIs, or application endpoints require their own access controls.
85
+
86
+ English and Traditional Chinese guides are included in the source distribution
87
+ under `docs/en` and `docs/zh-TW`.
@@ -0,0 +1,74 @@
1
+ # nxtlinq MCP Proxy
2
+
3
+ Deploy existing MCP servers on private Docker networks and check nxtlinq tool
4
+ permissions before forwarding each call. Your Agent connects to a single MCP
5
+ endpoint; downstream MCPs keep their original tools and account authentication.
6
+
7
+ **Start here:** [English guide](docs/en/quickstart.md) · [繁體中文指南](docs/zh-TW/quickstart.md)
8
+
9
+ [![Deployment topology](docs/assets/topology-en.svg)](docs/assets/topology-en.svg)
10
+
11
+ See [Topology and request flow](docs/en/architecture.md) for the authorization,
12
+ Setup, network, and resource boundaries.
13
+
14
+ ## Install and deploy
15
+
16
+ Follow the [environment guide](docs/en/environment.md) to prepare uv and Docker
17
+ Desktop or Colima, including Compose and Buildx. Skip components that already
18
+ pass the checks.
19
+
20
+ Then follow [Install and deploy](docs/en/quickstart.md):
21
+
22
+ 1. Install `nxtlinq-mcp-proxy[desktop]` with uv; dependencies are installed automatically.
23
+ 2. Package your MCP using `pack`, or supply an existing HTTP MCP image.
24
+ 3. Run `init` to configure service credentials, build the isolated deployment, and review/register tools.
25
+ 4. Open `setup` to configure identity and tool permissions.
26
+ 5. Connect your Agent and verify an allowed and a denied call.
27
+
28
+ Download: [nxtlinq MCP Proxy on PyPI](https://pypi.org/project/nxtlinq-mcp-proxy/0.1.0/).
29
+ The installation guide includes the complete uv command.
30
+
31
+ ## Product responsibilities
32
+
33
+ | Component | Responsibility |
34
+ | --- | --- |
35
+ | Proxy | Authenticate the MCP connection, check tool permissions, forward allowed calls |
36
+ | Deployment tooling | Build/run private MCP containers, configure mounts and permitted HTTPS destinations, verify isolation |
37
+ | Desktop Setup | User identity and nxtlinq tool permissions |
38
+ | Downstream MCP | Tool implementation, provider account login, data handling |
39
+ | Agent | Select and request tools through the MCP connection |
40
+
41
+ The primary interface is Streamable HTTP MCP with an Authorization header.
42
+ [Automatic Codex configuration](docs/en/agents.md) is an optional convenience;
43
+ other compatible clients use the same endpoint and authorization behavior.
44
+
45
+ ## Examples
46
+
47
+ The [example catalogue](docs/en/examples.md) explains what each recipe demonstrates
48
+ and the settings it needs:
49
+
50
+ - **Filesystem:** host folder sharing, read/write permissions, and container paths.
51
+ - **Memory:** persistent data across container recreation.
52
+ - **External API / GitHub PAT:** outbound destinations and backend credentials.
53
+ - **GitHub OAuth:** provider consent, callback routing, and an independent example login script.
54
+ - **Application control:** container browsers or connections to host application protocols.
55
+ - **Local computation:** tools that do not need external API access.
56
+
57
+ Follow the downstream MCP's instructions for external account login. The
58
+ [GitHub OAuth example](docs/en/authentication.md) provides its own login script.
59
+ Use `nxtlinq-mcp setup` to manage nxtlinq identity and tool permissions.
60
+
61
+ ## Scope and operation
62
+
63
+ A deployment supports 1–16 MCPs, one nxtlinq service, and one user's Setup session.
64
+ Each backend has its own internal network, no published tool port, a read-only
65
+ root filesystem, and only explicitly configured mounts and outbound destinations.
66
+
67
+ The local endpoint is bound to loopback. The Agent runs on the deployment host;
68
+ it is not contained by this deployment. Independent host file access, application
69
+ control endpoints, other APIs, and Docker administration remain outside the tool
70
+ permission boundary.
71
+
72
+ See [Operations and troubleshooting](docs/en/operations.md) for startup, updates,
73
+ folder sharing, tool registration, and diagnostics. See [Package an MCP](docs/en/packaging.md)
74
+ for generic npm/Python packaging and custom Dockerfile requirements.
@@ -0,0 +1,83 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1280" height="830" viewBox="0 0 1280 830" role="img" aria-labelledby="title desc">
2
+ <defs>
3
+ <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="context-stroke"/></marker>
4
+ </defs>
5
+ <style>
6
+ text { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans CJK TC', sans-serif; fill: #e5eaf2; }
7
+ .title { font-size: 26px; font-weight: 700; } .group { font-size: 13px; fill: #a3b1c8; letter-spacing: 1px; font-weight: 600; }
8
+ .label { font-size: 18px; font-weight: 650; } .body { font-size: 14px; fill: #bdc9dc; } .small { font-size: 12px; fill: #aab9d0; }
9
+ </style>
10
+ <rect width="1280" height="830" rx="16" fill="#10151e"/>
11
+
12
+ <title id="title">nxtlinq MCP Proxy — deployment topology</title>
13
+ <desc id="desc">Agent and Setup connect to the Proxy. The Proxy checks nxtlinq permissions before forwarding calls to isolated MCP servers. Each MCP accesses only explicitly configured resources. Denied calls do not reach an MCP.</desc>
14
+ <text x="30" y="42" class="title">nxtlinq MCP Proxy · deployment topology</text>
15
+ <rect x="320" y="75" width="585" height="115" rx="10" fill="#1b2331" stroke="#7573b9" stroke-width="1.5"/>
16
+ <text x="336" y="104" class="label">nxtlinq services</text>
17
+ <text x="336" y="130" class="body">Identity · tool catalogue · user permissions</text>
18
+ <text x="336" y="153" class="body">Service credentials stay on the Proxy side</text>
19
+ <rect x="22" y="75" width="252" height="565" rx="12" fill="none" stroke="#506382" stroke-dasharray="5 5"/>
20
+ <text x="37" y="99" class="group">DEPLOYMENT HOST / CLIENTS</text>
21
+ <rect x="290" y="267" width="663" height="426" rx="12" fill="none" stroke="#506382" stroke-dasharray="5 5"/>
22
+ <text x="305" y="291" class="group">DOCKER DEPLOYMENT</text>
23
+ <rect x="38" y="125" width="220" height="98" rx="10" fill="#1b2331" stroke="#40516b" stroke-width="1.5"/>
24
+ <text x="54" y="154" class="label">nxtlinq-mcp CLI</text>
25
+ <text x="54" y="180" class="body">init / up / down</text>
26
+ <text x="54" y="203" class="body">Manage Docker deployment</text>
27
+ <path d="M 258 175 L 282 175 L 282 267 L 290 267" fill="none" stroke="#a3b1c8" stroke-width="2" stroke-dasharray="5 5" marker-end="url(#arrow)"/>
28
+ <text x="40" y="246" class="small">Build / start containers</text>
29
+ <rect x="38" y="348" width="220" height="98" rx="10" fill="#1b2331" stroke="#40516b" stroke-width="1.5"/>
30
+ <text x="54" y="377" class="label">Agent</text>
31
+ <text x="54" y="403" class="body">Any compatible MCP client</text>
32
+ <text x="54" y="426" class="body">Codex auto-connect: optional</text>
33
+ <rect x="38" y="511" width="220" height="98" rx="10" fill="#1b2331" stroke="#40516b" stroke-width="1.5"/>
34
+ <text x="54" y="540" class="label">Desktop Setup</text>
35
+ <text x="54" y="566" class="body">Identity &amp; tool permissions</text>
36
+ <text x="54" y="589" class="body">Open: nxtlinq-mcp setup</text>
37
+ <rect x="310" y="340" width="253" height="247" rx="10" fill="#202b43" stroke="#87a4f3" stroke-width="1.5"/>
38
+ <text x="326" y="369" class="label">nxtlinq MCP Proxy</text>
39
+ <text x="326" y="395" class="body">MCP endpoint: 127.0.0.1:8765</text>
40
+ <text x="326" y="418" class="body">Setup API: 127.0.0.1:8766</text>
41
+ <text x="326" y="441" class="body">1. Identify the requested tool</text>
42
+ <text x="326" y="464" class="body">2. Check user permission</text>
43
+ <text x="326" y="487" class="body">3. Forward only if allowed</text>
44
+ <text x="326" y="515" class="small">Host-mapped endpoints above</text>
45
+ <rect x="326" y="533" width="220" height="34" rx="6" fill="#482c39"/>
46
+ <text x="338" y="555" class="body" style="fill:#ffb2be">Denied → return error</text>
47
+ <rect x="629" y="303" width="307" height="169" rx="12" fill="none" stroke="#59a793" stroke-dasharray="5 5"/>
48
+ <text x="644" y="327" class="group">PRIVATE NETWORK A</text>
49
+ <rect x="646" y="340" width="272" height="108" rx="10" fill="#1b2331" stroke="#59a793" stroke-width="1.5"/>
50
+ <text x="662" y="369" class="label">MCP A</text>
51
+ <text x="662" y="395" class="body">Original API-backed tools</text>
52
+ <text x="662" y="418" class="body">Tool port is not published</text>
53
+ <rect x="629" y="503" width="307" height="169" rx="12" fill="none" stroke="#59a793" stroke-dasharray="5 5"/>
54
+ <text x="644" y="527" class="group">PRIVATE NETWORK B</text>
55
+ <rect x="646" y="540" width="272" height="108" rx="10" fill="#1b2331" stroke="#59a793" stroke-width="1.5"/>
56
+ <text x="662" y="569" class="label">MCP B</text>
57
+ <text x="662" y="595" class="body">Original file / memory tools</text>
58
+ <text x="662" y="618" class="body">Tool port is not published</text>
59
+ <text x="984" y="289" class="group">CONFIGURED RESOURCES</text>
60
+ <rect x="985" y="334" width="272" height="142" rx="10" fill="#1b2331" stroke="#ba9c68" stroke-width="1.5"/>
61
+ <text x="1001" y="363" class="label">External APIs</text>
62
+ <text x="1001" y="389" class="body">Allowed destinations only</text>
63
+ <text x="1001" y="412" class="body">Via HTTPS egress proxy</text>
64
+ <text x="1001" y="435" class="body">Credentials belong to the MCP</text>
65
+ <rect x="985" y="540" width="272" height="112" rx="10" fill="#1b2331" stroke="#ba9c68" stroke-width="1.5"/>
66
+ <text x="1001" y="569" class="label">Files / persistent data</text>
67
+ <text x="1001" y="595" class="body">Selected host folder or volume</text>
68
+ <text x="1001" y="618" class="body">Explicit read / write mode</text>
69
+ <path d="M 258 395 L 310 395" fill="none" stroke="#84b9ff" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)"/>
70
+ <text x="40" y="332" class="small">MCP calls / results</text>
71
+ <path d="M 258 558 L 310 558" fill="none" stroke="#84b9ff" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)" stroke-dasharray="5 5"/>
72
+ <text x="40" y="495" class="small">Settings / session state</text>
73
+ <path d="M 437 340 L 437 190" fill="none" stroke="#84b9ff" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)" stroke-dasharray="5 5"/>
74
+ <text x="452" y="223" class="body">Identity / permission requests</text>
75
+ <text x="452" y="244" class="body">and service responses</text>
76
+ <path d="M 563 395 L 646 395" fill="none" stroke="#74d8b6" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)"/>
77
+ <path d="M 563 499 L 599 499 L 599 587 L 646 587" fill="none" stroke="#74d8b6" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)"/>
78
+ <path d="M 918 395 L 985 395" fill="none" stroke="#e4bf7f" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)"/>
79
+ <path d="M 918 587 L 985 587" fill="none" stroke="#e4bf7f" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)"/>
80
+ <text x="31" y="729" class="body">Blue: client and service traffic · Green: authorized tool forwarding · Gold: configured resource access</text>
81
+ <text x="31" y="760" class="body">Separate private network per MCP. No direct Agent → downstream MCP tool endpoint.</text>
82
+ <text x="31" y="786" class="small">Boundary: independently accessible host files, application endpoints and Docker admin access remain outside this control.</text>
83
+ </svg>
@@ -0,0 +1,83 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1280" height="830" viewBox="0 0 1280 830" role="img" aria-labelledby="title desc">
2
+ <defs>
3
+ <marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="context-stroke"/></marker>
4
+ </defs>
5
+ <style>
6
+ text { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans CJK TC', sans-serif; fill: #e5eaf2; }
7
+ .title { font-size: 26px; font-weight: 700; } .group { font-size: 13px; fill: #a3b1c8; letter-spacing: 1px; font-weight: 600; }
8
+ .label { font-size: 18px; font-weight: 650; } .body { font-size: 14px; fill: #bdc9dc; } .small { font-size: 12px; fill: #aab9d0; }
9
+ </style>
10
+ <rect width="1280" height="830" rx="16" fill="#10151e"/>
11
+
12
+ <title id="title">nxtlinq MCP Proxy — 部署拓樸</title>
13
+ <desc id="desc">Agent 與 Setup 連到 Proxy。Proxy 檢查 nxtlinq 權限後,才轉送工具呼叫至隔離的 MCP。各 MCP 只能使用明確配置的資源,未授權呼叫不會到達 MCP。</desc>
14
+ <text x="30" y="42" class="title">nxtlinq MCP Proxy · 部署拓樸</text>
15
+ <rect x="320" y="75" width="585" height="115" rx="10" fill="#1b2331" stroke="#7573b9" stroke-width="1.5"/>
16
+ <text x="336" y="104" class="label">nxtlinq 服務</text>
17
+ <text x="336" y="130" class="body">身分驗證 · 工具清單 · 使用者權限</text>
18
+ <text x="336" y="153" class="body">服務憑證保留於 Proxy 端</text>
19
+ <rect x="22" y="75" width="252" height="565" rx="12" fill="none" stroke="#506382" stroke-dasharray="5 5"/>
20
+ <text x="37" y="99" class="group">部署宿主 / 客戶端</text>
21
+ <rect x="290" y="267" width="663" height="426" rx="12" fill="none" stroke="#506382" stroke-dasharray="5 5"/>
22
+ <text x="305" y="291" class="group">DOCKER 部署</text>
23
+ <rect x="38" y="125" width="220" height="98" rx="10" fill="#1b2331" stroke="#40516b" stroke-width="1.5"/>
24
+ <text x="54" y="154" class="label">nxtlinq-mcp CLI</text>
25
+ <text x="54" y="180" class="body">init / up / down</text>
26
+ <text x="54" y="203" class="body">設定與管理 Docker 部署</text>
27
+ <path d="M 258 175 L 282 175 L 282 267 L 290 267" fill="none" stroke="#a3b1c8" stroke-width="2" stroke-dasharray="5 5" marker-end="url(#arrow)"/>
28
+ <text x="40" y="246" class="small">建置 / 啟動容器</text>
29
+ <rect x="38" y="348" width="220" height="98" rx="10" fill="#1b2331" stroke="#40516b" stroke-width="1.5"/>
30
+ <text x="54" y="377" class="label">Agent</text>
31
+ <text x="54" y="403" class="body">相容的 MCP 客戶端</text>
32
+ <text x="54" y="426" class="body">Codex 自動串接:選用</text>
33
+ <rect x="38" y="511" width="220" height="98" rx="10" fill="#1b2331" stroke="#40516b" stroke-width="1.5"/>
34
+ <text x="54" y="540" class="label">桌面 Setup</text>
35
+ <text x="54" y="566" class="body">身分與工具權限設定</text>
36
+ <text x="54" y="589" class="body">開啟:nxtlinq-mcp setup</text>
37
+ <rect x="310" y="340" width="253" height="247" rx="10" fill="#202b43" stroke="#87a4f3" stroke-width="1.5"/>
38
+ <text x="326" y="369" class="label">nxtlinq MCP Proxy</text>
39
+ <text x="326" y="395" class="body">MCP 入口:127.0.0.1:8765</text>
40
+ <text x="326" y="418" class="body">設定 API:127.0.0.1:8766</text>
41
+ <text x="326" y="441" class="body">1. 辨識本次呼叫的工具</text>
42
+ <text x="326" y="464" class="body">2. 檢查使用者權限</text>
43
+ <text x="326" y="487" class="body">3. 允許才轉送至下游</text>
44
+ <text x="326" y="515" class="small">以上為宿主映射入口</text>
45
+ <rect x="326" y="533" width="220" height="34" rx="6" fill="#482c39"/>
46
+ <text x="338" y="555" class="body" style="fill:#ffb2be">未授權 → 回傳拒絕</text>
47
+ <rect x="629" y="303" width="307" height="169" rx="12" fill="none" stroke="#59a793" stroke-dasharray="5 5"/>
48
+ <text x="644" y="327" class="group">私有網路 A</text>
49
+ <rect x="646" y="340" width="272" height="108" rx="10" fill="#1b2331" stroke="#59a793" stroke-width="1.5"/>
50
+ <text x="662" y="369" class="label">MCP A</text>
51
+ <text x="662" y="395" class="body">原 MCP 提供 API 工具</text>
52
+ <text x="662" y="418" class="body">工具連接埠不對宿主發布</text>
53
+ <rect x="629" y="503" width="307" height="169" rx="12" fill="none" stroke="#59a793" stroke-dasharray="5 5"/>
54
+ <text x="644" y="527" class="group">私有網路 B</text>
55
+ <rect x="646" y="540" width="272" height="108" rx="10" fill="#1b2331" stroke="#59a793" stroke-width="1.5"/>
56
+ <text x="662" y="569" class="label">MCP B</text>
57
+ <text x="662" y="595" class="body">原 MCP 提供檔案 / 記憶工具</text>
58
+ <text x="662" y="618" class="body">工具連接埠不對宿主發布</text>
59
+ <text x="984" y="289" class="group">明確配置的資源</text>
60
+ <rect x="985" y="334" width="272" height="142" rx="10" fill="#1b2331" stroke="#ba9c68" stroke-width="1.5"/>
61
+ <text x="1001" y="363" class="label">外部 API</text>
62
+ <text x="1001" y="389" class="body">只允許指定目的網域</text>
63
+ <text x="1001" y="412" class="body">經由 HTTPS 出口代理</text>
64
+ <text x="1001" y="435" class="body">憑證由下游 MCP 使用</text>
65
+ <rect x="985" y="540" width="272" height="112" rx="10" fill="#1b2331" stroke="#ba9c68" stroke-width="1.5"/>
66
+ <text x="1001" y="569" class="label">檔案 / 持久化資料</text>
67
+ <text x="1001" y="595" class="body">指定宿主資料夾或 volume</text>
68
+ <text x="1001" y="618" class="body">明確設定唯讀 / 可寫入</text>
69
+ <path d="M 258 395 L 310 395" fill="none" stroke="#84b9ff" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)"/>
70
+ <text x="40" y="332" class="small">MCP 呼叫 / 結果</text>
71
+ <path d="M 258 558 L 310 558" fill="none" stroke="#84b9ff" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)" stroke-dasharray="5 5"/>
72
+ <text x="40" y="495" class="small">設定 / 使用者狀態</text>
73
+ <path d="M 437 340 L 437 190" fill="none" stroke="#84b9ff" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)" stroke-dasharray="5 5"/>
74
+ <text x="452" y="223" class="body">身分 / 權限請求</text>
75
+ <text x="452" y="244" class="body">與服務回應</text>
76
+ <path d="M 563 395 L 646 395" fill="none" stroke="#74d8b6" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)"/>
77
+ <path d="M 563 499 L 599 499 L 599 587 L 646 587" fill="none" stroke="#74d8b6" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)"/>
78
+ <path d="M 918 395 L 985 395" fill="none" stroke="#e4bf7f" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)"/>
79
+ <path d="M 918 587 L 985 587" fill="none" stroke="#e4bf7f" stroke-width="2" marker-end="url(#arrow)" marker-start="url(#arrow)"/>
80
+ <text x="31" y="729" class="body">藍色:客戶端與服務互動 · 綠色:通過授權的工具轉送 · 金色:已配置的資源存取</text>
81
+ <text x="31" y="760" class="body">每個 MCP 各自使用私有網路;Agent 不直接連線到下游 MCP 工具端點。</text>
82
+ <text x="31" y="786" class="small">邊界:Agent 原有的宿主檔案、應用程式端點及 Docker 管理存取能力,不在此控管範圍。</text>
83
+ </svg>
@@ -0,0 +1,3 @@
1
+ # Install the current PyPI release.
2
+ --index-url https://pypi.org/simple
3
+ nxtlinq-mcp-proxy[desktop]==0.1.0
@@ -0,0 +1,71 @@
1
+ # Connect an Agent
2
+
3
+ nxtlinq MCP Proxy exposes a **Streamable HTTP MCP endpoint with an Authorization
4
+ header**. Choose a client that supports both. The current local deployment uses
5
+ a loopback URL, so the Agent runs on the deployment host.
6
+
7
+ The initialization wizard offers two connection options:
8
+
9
+ | Option | What it does |
10
+ | --- | --- |
11
+ | `codex` | Optional automatic configuration for Codex CLI |
12
+ | `other` | Displays connection details for manual client configuration |
13
+
14
+ The same Proxy, tool permissions, and private MCP deployment are used with either option.
15
+
16
+ ## Manual connection
17
+
18
+ From the deployment directory, with your environment active:
19
+
20
+ ```sh
21
+ nxtlinq-mcp connection --output connection.json
22
+ ```
23
+
24
+ Copy `url` and `headers.Authorization` into your Agent's MCP configuration.
25
+ Keep this file private. The command refuses to overwrite an existing file;
26
+ use a new filename after a restart and update the client with the new credential.
27
+ Complete Setup before calling tools.
28
+
29
+ ## Optional: automatic Codex configuration
30
+
31
+ Codex is currently the provided automatic integration. To use it, install Codex
32
+ CLI and verify `codex --version` in the terminal running the wizard, then select
33
+ `codex` during `init`.
34
+
35
+ The wizard adds the MCP connection while preserving existing model and other MCP
36
+ settings. Start a new session with your usual command:
37
+
38
+ ```sh
39
+ codex
40
+ ```
41
+
42
+ For an already-running deployment, automatic configuration is also available via:
43
+
44
+ ```sh
45
+ nxtlinq-mcp configure-codex
46
+ ```
47
+
48
+ The Proxy performs the same authorization checks regardless of client approval
49
+ settings. Approval inside the Agent does not grant nxtlinq permission.
50
+
51
+ ## Change the connection option
52
+
53
+ From the existing deployment directory, run:
54
+
55
+ ```sh
56
+ nxtlinq-mcp init .
57
+ ```
58
+
59
+ Select `other` for manual configuration or `codex` for automatic configuration.
60
+ Adding MCPs and syncing tools use the saved choice. Existing client connections
61
+ remain until you remove them in that client.
62
+
63
+ ## Troubleshoot optional Codex configuration
64
+
65
+ If Codex CLI is not found, install it and confirm `codex --version` works in the
66
+ terminal running the wizard. From the existing deployment directory, run
67
+ `nxtlinq-mcp init .` to retry. You can also choose manual configuration with `other`.
68
+
69
+ If an MCP connection name is already used, run `nxtlinq-mcp init . --advanced`
70
+ from that same directory and choose a different **Codex MCP server name**.
71
+ The wizard preserves the existing connection.
@@ -0,0 +1,59 @@
1
+ # Deployment topology
2
+
3
+ [![nxtlinq MCP Proxy deployment topology](../assets/topology-en.svg)](../assets/topology-en.svg)
4
+
5
+ Click the diagram to open it at full size. Ports shown are defaults; the wizard
6
+ can choose available ports. The two private networks illustrate separate MCPs.
7
+
8
+ ## Where each component runs
9
+
10
+ | Component | Location | Purpose |
11
+ | --- | --- | --- |
12
+ | `nxtlinq-mcp` CLI | Deployment host | Install/configure and manage the Docker deployment |
13
+ | Agent and desktop Setup | Deployment host | Request tools and configure permissions |
14
+ | Proxy service | Docker container | Check permissions and forward calls |
15
+ | Each downstream MCP | Separate Docker container | Execute its tools |
16
+
17
+ Installing the package with uv provides the CLI. `init` or `up` builds and starts
18
+ the container services. The diagram’s `127.0.0.1:8765` and `:8766` addresses are
19
+ **host-mapped endpoints**, not the containers’ internal listening addresses.
20
+
21
+ ## Tool call
22
+
23
+ 1. The Agent connects to the Proxy's Streamable HTTP endpoint with its connection credential.
24
+ 2. The Proxy checks the requested tool against the user's nxtlinq permissions.
25
+ 3. A denied call returns an error without invoking the downstream tool.
26
+ 4. An allowed call goes to the matching MCP on its private network; its result returns through the Proxy.
27
+
28
+ Only the Proxy exposes the tool endpoint to the Agent. Each downstream MCP has
29
+ its own internal Docker network and no published tool port.
30
+
31
+ ## Setup and service configuration
32
+
33
+ The operator configures the deployment's service credentials and registers its
34
+ tool catalogue. The user opens `nxtlinq-mcp setup` to complete identity and
35
+ permission settings. Setup connects to the Proxy's separate local settings
36
+ endpoint; the Proxy communicates with nxtlinq services. Service credentials are
37
+ not handed to the Agent.
38
+
39
+ ## Resources used by a downstream MCP
40
+
41
+ A Filesystem MCP needs an explicitly shared host folder. An API-backed MCP needs
42
+ permitted HTTPS destinations and any credentials required by that API. Outbound HTTPS goes through
43
+ an allowlisted egress proxy. Persistent data needs a configured volume and an MCP
44
+ that writes to it. These are optional settings, not requirements for every MCP.
45
+
46
+ External account login belongs to the downstream MCP. An OAuth example may add
47
+ a callback-only relay; that relay does not expose its MCP tool endpoint. The
48
+ [GitHub example](authentication.md) documents that additional flow.
49
+
50
+ ## Agent integrations
51
+
52
+ Any compatible client can use the MCP endpoint and authorization header.
53
+ [Codex automatic configuration](agents.md) is an optional convenience. It does
54
+ not change how authorization or downstream isolation works.
55
+
56
+ An Agent's own tools and separately accessible files, APIs, or application control
57
+ endpoints remain outside this deployment's authorization boundary. A user with
58
+ Docker administration rights can also change the deployment; Docker access must
59
+ not be treated as part of an untrusted Agent's tool environment.
@@ -0,0 +1,52 @@
1
+ # Example: GitHub OAuth
2
+
3
+ [Choose another example](examples.md)
4
+
5
+ The GitHub templates expose **`get_me` only**. GitHub authentication
6
+ permits access to your account; nxtlinq Setup separately permits tool execution.
7
+
8
+ ## OAuth browser login
9
+
10
+ Download the [GitHub OAuth example script](../examples/github_oauth_login.py){ download="github_oauth_login.py" }
11
+ (save the link as `github_oauth_login.py`) into your working directory, beside
12
+ the bundle and deployment directories. This script is specific to the GitHub
13
+ recipe. Complete [installation](quickstart.md) and activate your Proxy environment
14
+ before running it.
15
+
16
+ ```sh
17
+ nxtlinq-mcp pack github-login --template github-oauth
18
+ nxtlinq-mcp init github-tools --bundle github-login
19
+ cd github-tools
20
+ python ../github_oauth_login.py
21
+ nxtlinq-mcp setup
22
+ ```
23
+
24
+ The example script opens GitHub in your local browser and requests `read:user`. Complete
25
+ authorization there, then run `setup` to enable `get_me` and
26
+ [connect your Agent](agents.md). Ask it to identify the authenticated GitHub account.
27
+
28
+ The browser returns to `http://localhost:8085/callback` to finish login.
29
+ Port 8085 must be free. This address accepts login callbacks only; the backend's
30
+ tool port remains private. One GitHub OAuth
31
+ backend is supported per deployment, and concurrent deployments cannot share
32
+ that callback port. The browser must run on the deployment host.
33
+
34
+ Waiting expires after four minutes; the deployment and callback remain running.
35
+ Run the example script again to check the result or obtain a fresh authorization attempt.
36
+ The original MCP keeps OAuth tokens in memory, so backend recreation requires
37
+ another login. Stopping containers does not revoke the app in your GitHub account.
38
+
39
+ This helper supports only the GitHub OAuth example backend. For other MCPs,
40
+ follow their authentication requirements when configuring credentials and
41
+ allowed API destinations. The GitHub template allows `github.com` and
42
+ `api.github.com` automatically.
43
+
44
+ Sources: [GitHub account endpoint](https://docs.github.com/en/rest/users/users#get-the-authenticated-user),
45
+ [original MCP OAuth implementation guide](https://github.com/github/github-mcp-server/blob/v1.12.2/docs/oauth-login.md).
46
+
47
+ ## Callback troubleshooting
48
+
49
+ Keep the deployment running during browser consent. If the callback is refused,
50
+ check that port 8085 is available and the browser runs on the deployment host.
51
+ Rerun the example script to start a fresh attempt; a URL from a previous container
52
+ cannot resume a new login. This is separate from `nxtlinq-mcp setup`.