You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: packages/nowcoder/README.md
+44-15Lines changed: 44 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,9 +1,11 @@
1
1
# NowCoder ACM Problem MCP Server
2
2
3
-
Hardened local MCP server for public NowCoder ACM problem pages.
3
+
[简体中文](README.zh-CN.md)
4
+
5
+
Hardened local MCP server for allowlisted NowCoder ACM problem pages.
4
6
5
7
This is a standalone release workspace generated from the audited
6
-
[Kether Works OJ adapter source](https://github.com/ketherworks/oj-mcp-adapters/tree/3f7ee0e040d76f6dd5460d5926d8504c8cb20256/packages/nowcoder).
8
+
[Kether Works OJ adapter source](https://github.com/ketherworks/oj-mcp-adapters/tree/b23d435a4840f798e93c879a9e4f543529056a26/packages/nowcoder).
7
9
The release package bundles the shared OJ contract implementation, so its runtime does not depend
8
10
on unpublished workspace packages.
9
11
@@ -12,6 +14,7 @@ on unpublished workspace packages.
12
14
-`oj_capabilities`
13
15
-`oj_health`
14
16
-`oj_fetch_problem`
17
+
-`nowcoder_auth_status`
15
18
16
19
## Local Stdio
17
20
@@ -44,9 +47,12 @@ publication are intentionally separate steps and are not claimed until their own
44
47
## Policy
45
48
46
49
This project is unofficial and is not affiliated with or endorsed by NowCoder.
47
-
It never bypasses anti-bot challenges and intentionally remains local stdio only.
50
+
It supports an optional startup-injected local session, never bypasses anti-bot challenges, and
51
+
intentionally remains local stdio only.
48
52
49
-
The server exposes no run or submit tool. It accepts no judge account credentials. See
53
+
The server exposes no run or submit tool. The server accepts an optional NowCoder Cookie only from `NOWCODER_SESSION_COOKIE` at local
54
+
stdio process startup. Inject it from a trusted secret manager; never put it in tool arguments,
55
+
MCP configuration files, command-line arguments, logs, or committed files. See
50
56
[SECURITY.md](SECURITY.md) for the security boundary and [PROVENANCE.md](PROVENANCE.md) for the
51
57
canonical source revision.
52
58
@@ -66,15 +72,36 @@ this repository.
66
72
67
73
## Provider Implementation Details
68
74
69
-
Read-only MCP adapter for official public NowCoder/牛客 ACM problem pages. This package is an unofficial page adapter; it does not use or claim an official NowCoder API.
75
+
[简体中文](README.zh-CN.md)
76
+
77
+
Read-only MCP adapter for official NowCoder/牛客 ACM problem pages. It is an unofficial page adapter and does not use or claim an official NowCoder API.
70
78
71
79
## Tools
72
80
73
-
-`oj_capabilities`: reports the single audited fetch capability and every unsupported operation.
81
+
-`oj_capabilities`: reports the audited fetch capability, its active authentication mode, and every unsupported operation.
74
82
-`oj_health`: reports passive health from the last fetch without making a network probe.
75
-
-`oj_fetch_problem`: returns an `OjProblemDocument` from one allowlisted public page URL or canonical native ID.
83
+
-`oj_fetch_problem`: returns an `OjProblemDocument` from one allowlisted page URL or canonical native ID.
84
+
-`nowcoder_auth_status`: checks whether the startup-injected local session is accepted without returning account identity or Cookie data.
85
+
86
+
`oj_search_problems` is intentionally absent because no stable problem-search contract has been audited. Browser import, profiles, submissions, execution, and judging are also absent. Configuring a session does not enable those operations.
87
+
88
+
## Local Session
89
+
90
+
Authentication is optional. Without a session, the server reads pages that NowCoder exposes publicly. With a session, the same allowlisted page requests include the user-provided Cookie header and capabilities report `session_cookie` with `R1_private_read` risk.
91
+
92
+
The server reads a complete Cookie request-header value from `NOWCODER_SESSION_COOKIE` once at process startup. A trusted launcher should obtain the value from a secret manager, such as VS Code `SecretStorage`, and inject it only into the local stdio child process.
93
+
94
+
Do not put the Cookie in MCP tool arguments, `mcp.json`, VS Code settings, command-line arguments, shell history, logs, issues, or committed files. This adapter does not extract browser cookies automatically. Restart the process after rotating the session.
95
+
96
+
`nowcoder_auth_status` checks the fixed URL `https://ac.nowcoder.com/` and returns one redacted state:
97
+
98
+
-`not_configured`
99
+
-`authenticated`
100
+
-`expired`
101
+
-`challenge`
102
+
-`unknown`
76
103
77
-
`oj_search_problems` is intentionally absent. The public problem-list page is useful to humans, but no stable anonymous search contract has been audited. Browser import, cookies, authentication, profiles, submissions, execution, and judging are also absent.
104
+
The status result never contains the Cookie, account identity, or response HTML.
Query strings and fragments are discarded. Other NowCoder products and legacy URL shapes are rejected until they can be independently audited.
115
+
Query strings and fragments are discarded. Other NowCoder products and legacy URL shapes are rejected until independently audited.
89
116
90
117
The alternative `nativeId` input accepts exactly these deterministic forms:
91
118
@@ -99,15 +126,17 @@ Numeric contest indexes are also accepted. Bare numbers, leading zeroes, lowerca
99
126
## Safety
100
127
101
128
- URL scheme, hostname, port, credentials, and path are allowlisted before every request and redirect.
102
-
- DNS A and AAAA queries use a cancellation-capable Node resolver under the shared deadline. Every answer must be public unicast; IANA non-global ranges and transition addresses with embedded non-global IPv4 targets are rejected. The complete validated dual-stack answer set is pinned into TLS fallback while preserving hostname verification and SNI.
129
+
- The optional Cookie is attached only after the destination passes the exact `ac.nowcoder.com` allowlist. A redirect is validated before any follow-up request can receive it.
130
+
- DNS A and AAAA queries use a cancellation-capable Node resolver under the shared deadline. Every answer must be public unicast; validated addresses are pinned into TLS fallback while preserving hostname verification and SNI.
103
131
- Redirects are manual and limited to two allowlisted hops.
104
-
- One 10-second deadline covers DNS, response body transfer, and every redirect hop; abort listeners and sockets are cleaned up when the operation settles. Responses are capped at 2 MiB of UTF-8 HTML.
105
-
- Anti-bot pages produce `challenge.required`; the adapter never attempts to bypass them.
106
-
- Responses are normalized from the same public ACM DOM used by Competitive Companion, with required input/output sections, source provenance, and SHA-256 hashes on text blocks. Missing required sections fail as `upstream.schema_changed`.
132
+
- One 10-second deadline covers DNS, response-body transfer, and every redirect hop. Responses are capped at 2 MiB of UTF-8 HTML; the startup Cookie is capped at 16 KiB and control characters are rejected.
133
+
- Anti-bot pages produce `challenge.required`; the adapter does not use browser automation or attempt to bypass them.
134
+
- Responses are normalized from the official ACM DOM with required input/output sections, source provenance, and SHA-256 hashes on text blocks. Missing required sections fail as `upstream.schema_changed`.
135
+
- Tool inputs have no Cookie or credential field, and errors and status results are deliberately redacted.
107
136
108
137
## Transport Choice
109
138
110
-
The package exposes stdio only. A Worker was deliberately omitted: a public HTTP deployment would become an anonymous NowCoder page-fetch relay, while the Worker runtime cannot provide the same explicit DNS resolution and TLS address pinning used by this Node adapter. Keeping the process local also avoids amplifying rate limits and challenge traffic. The implementation is stateless apart from passive last-fetch health, but that alone is not enough to make a public relay prudent.
139
+
The package exposes local stdio only. It must not be deployed as a shared HTTP service while session forwarding is enabled. Keeping authenticated requests local prevents the server from becoming a credential-forwarding or page-fetch relay and preserves the Node transport's DNS and TLS pinning controls.
111
140
112
141
## Development
113
142
@@ -122,4 +151,4 @@ npm run pack:check
122
151
npm start
123
152
```
124
153
125
-
Tests use static fixtures and loopback-only TLS servers. They do not contact NowCoder or deploy any service.
154
+
Tests use synthetic sessions, static fixtures, and loopback-only TLS servers. They do not contact NowCoder, access browser secrets, or deploy any service.
0 commit comments