fa-mcp-sdk 0.4.142 → 0.11.4

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 (201) hide show
  1. package/README.md +5 -0
  2. package/cli-template/.dockerignore +16 -0
  3. package/cli-template/.gitlab-ci.yml +135 -0
  4. package/cli-template/AGENTS.md +2 -0
  5. package/cli-template/CHANGELOG.md +64 -0
  6. package/cli-template/FA-MCP-SDK-DOC/00-FA-MCP-SDK-index.md +28 -4
  7. package/cli-template/FA-MCP-SDK-DOC/02-1-tools-and-api.md +195 -0
  8. package/cli-template/FA-MCP-SDK-DOC/02-2-prompts-and-resources.md +172 -9
  9. package/cli-template/FA-MCP-SDK-DOC/03-configuration.md +170 -12
  10. package/cli-template/FA-MCP-SDK-DOC/04-authentication.md +158 -8
  11. package/cli-template/FA-MCP-SDK-DOC/06-utilities.md +67 -6
  12. package/cli-template/FA-MCP-SDK-DOC/07-testing-and-operations.md +31 -15
  13. package/cli-template/FA-MCP-SDK-DOC/10-mcp-apps.md +1 -1
  14. package/cli-template/FA-MCP-SDK-DOC/11-public-contract.md +342 -0
  15. package/cli-template/FA-MCP-SDK-DOC/12-implementation-standard.md +1148 -0
  16. package/cli-template/README.md +37 -0
  17. package/cli-template/deploy/docker/.env.example +10 -0
  18. package/cli-template/deploy/docker/Dockerfile +44 -0
  19. package/cli-template/deploy/docker/Dockerfile.local +29 -0
  20. package/cli-template/deploy/docker/README.md +94 -0
  21. package/cli-template/deploy/docker/config/local.docker.yaml +14 -0
  22. package/cli-template/deploy/docker/docker-compose.yml +31 -0
  23. package/cli-template/deploy/gitlab-runner/.env.example +16 -0
  24. package/cli-template/deploy/gitlab-runner/README.md +65 -0
  25. package/cli-template/deploy/gitlab-runner/config/config.toml.template +26 -0
  26. package/cli-template/deploy/gitlab-runner/docker-compose.yml +39 -0
  27. package/cli-template/deploy/gitlab-runner/entrypoint.sh +27 -0
  28. package/cli-template/deploy/gitlab-runner/start.sh +47 -0
  29. package/cli-template/gitignore +96 -95
  30. package/cli-template/package.json +1 -1
  31. package/config/_local.yaml +73 -11
  32. package/config/custom-environment-variables.yaml +102 -0
  33. package/config/default.yaml +164 -11
  34. package/config/local.yaml +20 -19
  35. package/dist/core/_types_/config.d.ts +119 -0
  36. package/dist/core/_types_/config.d.ts.map +1 -1
  37. package/dist/core/_types_/types.d.ts +137 -4
  38. package/dist/core/_types_/types.d.ts.map +1 -1
  39. package/dist/core/agent-tester/agent-tester-router.d.ts.map +1 -1
  40. package/dist/core/agent-tester/agent-tester-router.js +25 -11
  41. package/dist/core/agent-tester/agent-tester-router.js.map +1 -1
  42. package/dist/core/agent-tester/services/TesterMcpClientService.d.ts.map +1 -1
  43. package/dist/core/agent-tester/services/TesterMcpClientService.js +6 -4
  44. package/dist/core/agent-tester/services/TesterMcpClientService.js.map +1 -1
  45. package/dist/core/auth/admin-auth.js +4 -4
  46. package/dist/core/auth/admin-auth.js.map +1 -1
  47. package/dist/core/auth/agent-tester-auth.d.ts +1 -1
  48. package/dist/core/auth/agent-tester-auth.d.ts.map +1 -1
  49. package/dist/core/auth/agent-tester-auth.js +8 -4
  50. package/dist/core/auth/agent-tester-auth.js.map +1 -1
  51. package/dist/core/auth/auth-profile.d.ts +38 -0
  52. package/dist/core/auth/auth-profile.d.ts.map +1 -0
  53. package/dist/core/auth/auth-profile.js +101 -0
  54. package/dist/core/auth/auth-profile.js.map +1 -0
  55. package/dist/core/auth/jwt-v2.d.ts +27 -0
  56. package/dist/core/auth/jwt-v2.d.ts.map +1 -0
  57. package/dist/core/auth/jwt-v2.js +180 -0
  58. package/dist/core/auth/jwt-v2.js.map +1 -0
  59. package/dist/core/auth/jwt.d.ts +27 -13
  60. package/dist/core/auth/jwt.d.ts.map +1 -1
  61. package/dist/core/auth/jwt.js +36 -13
  62. package/dist/core/auth/jwt.js.map +1 -1
  63. package/dist/core/auth/key-resolver.d.ts +74 -0
  64. package/dist/core/auth/key-resolver.d.ts.map +1 -0
  65. package/dist/core/auth/key-resolver.js +330 -0
  66. package/dist/core/auth/key-resolver.js.map +1 -0
  67. package/dist/core/auth/middleware.d.ts.map +1 -1
  68. package/dist/core/auth/middleware.js +66 -0
  69. package/dist/core/auth/middleware.js.map +1 -1
  70. package/dist/core/auth/multi-auth.d.ts +1 -1
  71. package/dist/core/auth/multi-auth.d.ts.map +1 -1
  72. package/dist/core/auth/multi-auth.js +7 -7
  73. package/dist/core/auth/multi-auth.js.map +1 -1
  74. package/dist/core/auth/token-generator/server.js +4 -4
  75. package/dist/core/auth/token-generator/server.js.map +1 -1
  76. package/dist/core/auth/types.d.ts +5 -0
  77. package/dist/core/auth/types.d.ts.map +1 -1
  78. package/dist/core/db/pg-db.d.ts +7 -0
  79. package/dist/core/db/pg-db.d.ts.map +1 -1
  80. package/dist/core/db/pg-db.js +54 -3
  81. package/dist/core/db/pg-db.js.map +1 -1
  82. package/dist/core/errors/BaseMcpError.d.ts +21 -1
  83. package/dist/core/errors/BaseMcpError.d.ts.map +1 -1
  84. package/dist/core/errors/BaseMcpError.js +20 -1
  85. package/dist/core/errors/BaseMcpError.js.map +1 -1
  86. package/dist/core/errors/ValidationError.d.ts +5 -0
  87. package/dist/core/errors/ValidationError.d.ts.map +1 -1
  88. package/dist/core/errors/ValidationError.js +6 -1
  89. package/dist/core/errors/ValidationError.js.map +1 -1
  90. package/dist/core/errors/errors.d.ts +31 -3
  91. package/dist/core/errors/errors.d.ts.map +1 -1
  92. package/dist/core/errors/errors.js +86 -6
  93. package/dist/core/errors/errors.js.map +1 -1
  94. package/dist/core/errors/specific-errors.d.ts +54 -0
  95. package/dist/core/errors/specific-errors.d.ts.map +1 -0
  96. package/dist/core/errors/specific-errors.js +82 -0
  97. package/dist/core/errors/specific-errors.js.map +1 -0
  98. package/dist/core/index.d.ts +10 -2
  99. package/dist/core/index.d.ts.map +1 -1
  100. package/dist/core/index.js +9 -1
  101. package/dist/core/index.js.map +1 -1
  102. package/dist/core/init-mcp-server.d.ts.map +1 -1
  103. package/dist/core/init-mcp-server.js +39 -0
  104. package/dist/core/init-mcp-server.js.map +1 -1
  105. package/dist/core/mcp/create-mcp-server.d.ts +12 -6
  106. package/dist/core/mcp/create-mcp-server.d.ts.map +1 -1
  107. package/dist/core/mcp/create-mcp-server.js +592 -33
  108. package/dist/core/mcp/create-mcp-server.js.map +1 -1
  109. package/dist/core/mcp/debug-trace.d.ts +3 -1
  110. package/dist/core/mcp/debug-trace.d.ts.map +1 -1
  111. package/dist/core/mcp/debug-trace.js +17 -2
  112. package/dist/core/mcp/debug-trace.js.map +1 -1
  113. package/dist/core/mcp/deprecation.d.ts +31 -0
  114. package/dist/core/mcp/deprecation.d.ts.map +1 -0
  115. package/dist/core/mcp/deprecation.js +96 -0
  116. package/dist/core/mcp/deprecation.js.map +1 -0
  117. package/dist/core/mcp/mcp-logging.d.ts +32 -0
  118. package/dist/core/mcp/mcp-logging.d.ts.map +1 -0
  119. package/dist/core/mcp/mcp-logging.js +97 -0
  120. package/dist/core/mcp/mcp-logging.js.map +1 -0
  121. package/dist/core/mcp/pagination.d.ts +13 -0
  122. package/dist/core/mcp/pagination.d.ts.map +1 -0
  123. package/dist/core/mcp/pagination.js +50 -0
  124. package/dist/core/mcp/pagination.js.map +1 -0
  125. package/dist/core/mcp/prompts.d.ts +5 -1
  126. package/dist/core/mcp/prompts.d.ts.map +1 -1
  127. package/dist/core/mcp/prompts.js +3 -1
  128. package/dist/core/mcp/prompts.js.map +1 -1
  129. package/dist/core/mcp/resources.d.ts +9 -0
  130. package/dist/core/mcp/resources.d.ts.map +1 -1
  131. package/dist/core/mcp/resources.js +158 -11
  132. package/dist/core/mcp/resources.js.map +1 -1
  133. package/dist/core/mcp/server-stdio.d.ts +7 -1
  134. package/dist/core/mcp/server-stdio.d.ts.map +1 -1
  135. package/dist/core/mcp/server-stdio.js +8 -3
  136. package/dist/core/mcp/server-stdio.js.map +1 -1
  137. package/dist/core/mcp/task-store.d.ts +97 -0
  138. package/dist/core/mcp/task-store.d.ts.map +1 -0
  139. package/dist/core/mcp/task-store.js +175 -0
  140. package/dist/core/mcp/task-store.js.map +1 -0
  141. package/dist/core/mcp/tool-limits.d.ts +22 -0
  142. package/dist/core/mcp/tool-limits.d.ts.map +1 -0
  143. package/dist/core/mcp/tool-limits.js +115 -0
  144. package/dist/core/mcp/tool-limits.js.map +1 -0
  145. package/dist/core/mcp/validate-tool-args.d.ts +16 -0
  146. package/dist/core/mcp/validate-tool-args.d.ts.map +1 -0
  147. package/dist/core/mcp/validate-tool-args.js +67 -0
  148. package/dist/core/mcp/validate-tool-args.js.map +1 -0
  149. package/dist/core/mcp/validate-tool-names.d.ts +11 -0
  150. package/dist/core/mcp/validate-tool-names.d.ts.map +1 -0
  151. package/dist/core/mcp/validate-tool-names.js +23 -0
  152. package/dist/core/mcp/validate-tool-names.js.map +1 -0
  153. package/dist/core/metrics/metrics.d.ts +45 -0
  154. package/dist/core/metrics/metrics.d.ts.map +1 -0
  155. package/dist/core/metrics/metrics.js +119 -0
  156. package/dist/core/metrics/metrics.js.map +1 -0
  157. package/dist/core/utils/mask-sensitive.d.ts +44 -0
  158. package/dist/core/utils/mask-sensitive.d.ts.map +1 -0
  159. package/dist/core/utils/mask-sensitive.js +64 -0
  160. package/dist/core/utils/mask-sensitive.js.map +1 -0
  161. package/dist/core/utils/testing/McpHttpClient.d.ts +8 -33
  162. package/dist/core/utils/testing/McpHttpClient.d.ts.map +1 -1
  163. package/dist/core/utils/testing/McpHttpClient.js +8 -74
  164. package/dist/core/utils/testing/McpHttpClient.js.map +1 -1
  165. package/dist/core/utils/testing/McpStreamableHttpClient.d.ts +24 -30
  166. package/dist/core/utils/testing/McpStreamableHttpClient.d.ts.map +1 -1
  167. package/dist/core/utils/testing/McpStreamableHttpClient.js +36 -198
  168. package/dist/core/utils/testing/McpStreamableHttpClient.js.map +1 -1
  169. package/dist/core/utils/utils.d.ts.map +1 -1
  170. package/dist/core/utils/utils.js +2 -0
  171. package/dist/core/utils/utils.js.map +1 -1
  172. package/dist/core/web/admin-router.js +3 -3
  173. package/dist/core/web/admin-router.js.map +1 -1
  174. package/dist/core/web/cors.d.ts +9 -1
  175. package/dist/core/web/cors.d.ts.map +1 -1
  176. package/dist/core/web/cors.js +26 -5
  177. package/dist/core/web/cors.js.map +1 -1
  178. package/dist/core/web/event-store.d.ts +33 -0
  179. package/dist/core/web/event-store.d.ts.map +1 -0
  180. package/dist/core/web/event-store.js +65 -0
  181. package/dist/core/web/event-store.js.map +1 -0
  182. package/dist/core/web/oauth-router.d.ts +37 -0
  183. package/dist/core/web/oauth-router.d.ts.map +1 -0
  184. package/dist/core/web/oauth-router.js +207 -0
  185. package/dist/core/web/oauth-router.js.map +1 -0
  186. package/dist/core/web/request-id.d.ts +44 -0
  187. package/dist/core/web/request-id.d.ts.map +1 -0
  188. package/dist/core/web/request-id.js +82 -0
  189. package/dist/core/web/request-id.js.map +1 -0
  190. package/dist/core/web/server-http.d.ts.map +1 -1
  191. package/dist/core/web/server-http.js +322 -182
  192. package/dist/core/web/server-http.js.map +1 -1
  193. package/package.json +15 -2
  194. package/scripts/claude-2-agents-symlink.js +10 -1
  195. package/scripts/generate-jwt.js +129 -51
  196. package/src/template/custom-resources.ts +14 -0
  197. package/src/template/prompts/custom-prompts.ts +4 -0
  198. package/src/template/tools/handle-tool-call.ts +59 -3
  199. package/src/template/tools/tools.ts +92 -31
  200. package/src/tests/mcp/test-http.js +1 -1
  201. package/src/tests/mcp/test-sse.js +1 -1
@@ -0,0 +1,1148 @@
1
+ # Corporate MCP Server Implementation Standard
2
+
3
+ | Parameter | Value |
4
+ |----------------------------|------------------------------------|
5
+ | Version | 1.2 |
6
+ | Status | Active |
7
+ | Date | 2026-06-03 |
8
+ | Scope | All internal company MCP servers |
9
+ | Base MCP | MCP 2025-11-25 |
10
+ | Starter SDK (optional) | `fa-mcp-sdk` |
11
+ | Owner | AI/MCP Platform team |
12
+
13
+ > This document is the English translation of the corporate implementation standard. It restates the
14
+ > explicit MCP 2025-11-25 requirements plus the corporate Avatar / AI Platform profile in a single
15
+ > self-contained document. Version 1.2 adds the side-effect tools and risk-level rules and fixes the
16
+ > `-32007` error-code inconsistency.
17
+
18
+ ## Table of Contents
19
+
20
+ 1. [Purpose and scope](#1-purpose-and-scope)
21
+ 2. [Terminology and requirement levels](#2-terminology-and-requirement-levels)
22
+ 3. [Compatibility with MCP 2025-11-25](#3-compatibility-with-mcp-2025-11-25)
23
+ 4. [MCP protocol versioning](#4-mcp-protocol-versioning)
24
+ 5. [Transports](#5-transports)
25
+ 6. [HTTP interface](#6-http-interface)
26
+ 7. [Authentication and authorization](#7-authentication-and-authorization)
27
+ 8. [MCP methods and lifecycle](#8-mcp-methods-and-lifecycle)
28
+ 9. [Tools: external contract](#9-tools-external-contract)
29
+ 10. [Prompts: external contract](#10-prompts-external-contract)
30
+ 11. [Resources: external contract](#11-resources-external-contract)
31
+ 12. [Result format](#12-result-format)
32
+ 13. [Error format](#13-error-format)
33
+ 14. [Limits and protection](#14-limits-and-protection)
34
+ 15. [Observability](#15-observability)
35
+ 16. [Health and readiness](#16-health-and-readiness)
36
+ 17. [Contract stability and deprecation](#17-contract-stability-and-deprecation)
37
+ 18. [Compliance checklist](#18-compliance-checklist)
38
+ 19. [Appendix A. Auth profile](#appendix-a-auth-profile)
39
+ 20. [Appendix B. Error codes](#appendix-b-error-codes)
40
+ 21. [Appendix C. Input / output summary table](#appendix-c-input--output-summary-table)
41
+
42
+ ---
43
+
44
+ ## 1. Purpose and scope
45
+
46
+ This document defines the corporate profile of an MCP server developed in-house. It builds on the common
47
+ MCP 2025-11-25 protocol and adds internal Avatar / AI Platform requirements for security, network
48
+ interface, naming, observability, and operational contracts.
49
+
50
+ The document covers:
51
+
52
+ - transport and network interface;
53
+ - authentication and authorization;
54
+ - the set of published tools, prompts, and resources;
55
+ - result and error formats;
56
+ - operational requirements (health, observability, limits);
57
+ - rules for evolving the public contract.
58
+
59
+ The internal implementation, language, framework, and architecture are **not regulated**. A server may be
60
+ built on any technology stack as long as it fully complies with the external requirements of this standard.
61
+ To speed up the start, a team MAY use `fa-mcp-sdk`, the official MCP SDK, or its own implementation.
62
+
63
+ The standard applies to servers exposed to:
64
+
65
+ - internal company AI agents;
66
+ - internal services via MCP clients;
67
+ - partner environments, if the server is published beyond the perimeter.
68
+
69
+ The standard **does not apply** to local experimental servers without external consumers.
70
+
71
+ ## 2. Terminology and requirement levels
72
+
73
+ The RFC 2119 keywords are used:
74
+
75
+ | Term | Meaning |
76
+ | --------------- | -------------------------------------------------------- |
77
+ | MUST | Hard requirement. Non-compliance = acceptance blocker. |
78
+ | SHOULD | Recommended. A deviation requires a justification in the README. |
79
+ | MAY | Allowed at the team's discretion. |
80
+
81
+ Other terms:
82
+
83
+ - **Public contract** — the set of all externally visible elements of the server, listed in §17.
84
+ - **Breaking change** — any change to the public contract that breaks existing clients.
85
+ - **Starter SDK** — one of the allowed ways to speed up the start of implementation; it is not part of the
86
+ public contract and does not constrain the language or internal architecture of the server.
87
+ - **Corporate profile** — additional company requirements on top of common MCP. If a requirement is marked
88
+ as corporate, it is not a universal MCP requirement, but it is mandatory for internal servers.
89
+
90
+ ## 3. Compatibility with MCP 2025-11-25
91
+
92
+ This standard is compatible with MCP 2025-11-25 and must be treated as a corporate profile on top of the
93
+ common protocol.
94
+
95
+ Base MCP 2025-11-25 requirements:
96
+
97
+ - JSON-RPC 2.0 is used for all MCP messages;
98
+ - server and client go through the `initialize` / `initialized` lifecycle;
99
+ - both parties declare and respect negotiated capabilities;
100
+ - standard transports: `stdio` and Streamable HTTP;
101
+ - the HTTP transport uses a single MCP endpoint, usually `/mcp`, with `POST` and an optional `GET` for the
102
+ SSE stream;
103
+ - `MCP-Protocol-Version` is sent on subsequent HTTP requests after negotiation;
104
+ - `MCP-Session-Id` is used only as a session identifier and does not replace authentication;
105
+ - `tools`, `prompts`, `resources`, `logging`, `completions`, `tasks` are used only if the capability has
106
+ been declared and negotiated.
107
+
108
+ Corporate extensions of this standard:
109
+
110
+ - mandatory authentication for internal HTTP / Streamable HTTP MCP servers;
111
+ - a corporate JWT / opaque token profile for internal environments;
112
+ - preserving snake_case tool names;
113
+ - recommended prompts `agent_brief` and `agent_prompt` for Avatar routing;
114
+ - corporate URI schemes `use://`, `project://`, `doc://`;
115
+ - mandatory limits, observability, health/readiness, and CHANGELOG.
116
+
117
+ If a server is published for generic MCP clients beyond the internal perimeter, it SHOULD follow common
118
+ MCP 2025-11-25 for authorization discovery, Streamable HTTP, and the error model. If a server is available
119
+ only to internal Avatar clients, the corporate profile is allowed, provided it is explicitly documented in
120
+ the README and `use://auth`.
121
+
122
+ ## 4. MCP protocol versioning
123
+
124
+ The server MUST:
125
+
126
+ - declare the supported MCP protocol version in the `initialize` response;
127
+ - support MCP 2025-11-25 for new HTTP / Streamable HTTP servers unless the README states another version;
128
+ - return a standard `initialize` error on version mismatch instead of crashing;
129
+ - for the HTTP transport, accept `MCP-Protocol-Version` on subsequent requests and return HTTP 400 for an
130
+ explicitly unsupported version.
131
+
132
+ The server MUST maintain its own semver versioning:
133
+
134
+ | Change | Version bump |
135
+ | --------------------------------------- | ------------ |
136
+ | Breaking change to the public contract | MAJOR |
137
+ | New tool / prompt / resource | MINOR |
138
+ | Bugfix without a contract change | PATCH |
139
+
140
+ The server version MUST be available through:
141
+
142
+ - the `/health` response (the `version` field);
143
+ - `serverInfo.version` in `initialize.result`;
144
+ - the `project://version` resource (SHOULD).
145
+
146
+ ## 5. Transports
147
+
148
+ The server MUST support at least one transport. Allowed transports:
149
+
150
+ | Transport | Purpose | When mandatory |
151
+ | ----------------- | ---------------------------------------- | -------------- |
152
+ | `stdio` | Local launch (Claude Desktop, etc.) | if the server targets a desktop agent |
153
+ | `streamable_http` | Corporate network access per MCP 2025-11-25 | for all new network MCP servers (MUST) |
154
+ | `legacy_http_sse` | Compatibility with the old HTTP+SSE transport | MAY for existing clients |
155
+ | custom | Specialized transport | MAY with explicit documentation |
156
+
157
+ The semantics of MCP calls MUST be identical across all declared transports.
158
+
159
+ For `stdio`:
160
+
161
+ - the server reads JSON-RPC messages from `stdin` and writes only valid MCP messages to `stdout`;
162
+ - logs are allowed only on `stderr`;
163
+ - messages are newline-delimited and MUST NOT contain an embedded newline.
164
+
165
+ For `streamable_http`:
166
+
167
+ - the server MUST expose a single MCP endpoint, usually `/mcp`;
168
+ - the client sends each JSON-RPC message as a separate `POST /mcp`;
169
+ - the server MAY use an SSE stream via `GET /mcp` or via a `POST /mcp` response with
170
+ `Content-Type: text/event-stream`;
171
+ - a separate `/sse` endpoint is NOT the primary transport of MCP 2025-11-25 and is allowed only as a legacy
172
+ compatibility path.
173
+
174
+ ## 6. HTTP interface
175
+
176
+ For servers with Streamable HTTP:
177
+
178
+ | Endpoint | Method | Level | Purpose |
179
+ | ---------- | ------ | ----- | ------------------------------------ |
180
+ | `/mcp` | POST | MUST | Main MCP endpoint (JSON-RPC 2.0) |
181
+ | `/mcp` | GET | MAY | SSE stream from server to client; return 405 if not supported |
182
+ | `/mcp` | DELETE | MAY | Explicit MCP session termination |
183
+ | `/health` | GET | MUST | Liveness check |
184
+ | `/ready` | GET | SHOULD | Readiness check |
185
+ | `/sse` | GET | MAY, legacy only | Old HTTP+SSE transport for backward compatibility |
186
+ | `/` | GET | SHOULD | Service HTML page / redirect to documentation |
187
+
188
+ Requirements for `POST /mcp`:
189
+
190
+ - `Content-Type: application/json` on input;
191
+ - `Accept` MUST include `application/json` and `text/event-stream`;
192
+ - the body is a single valid JSON-RPC 2.0 request, notification, or response;
193
+ - if the input is a request, the server returns a single JSON response (`application/json`) or an SSE
194
+ stream (`text/event-stream`);
195
+ - if the input is a notification or response and the server accepted the message, the server returns
196
+ HTTP 202 with no body;
197
+ - the server MUST respond with a valid JSON-RPC error rather than HTML or plain text on a protocol-level
198
+ failure.
199
+
200
+ Requirements for `GET /mcp`:
201
+
202
+ - `Accept` MUST include `text/event-stream`;
203
+ - if the SSE stream is supported, the server returns `Content-Type: text/event-stream`;
204
+ - if the SSE stream is not supported, the server returns HTTP 405 Method Not Allowed;
205
+ - the server MUST NOT send a JSON-RPC response on an independent GET stream, except for the resume scenario
206
+ via `Last-Event-ID`.
207
+
208
+ MCP HTTP headers:
209
+
210
+ | Header | Level | Behavior |
211
+ | ------ | ----- | -------- |
212
+ | `MCP-Protocol-Version` | MUST for HTTP after `initialize` | The protocol version negotiated in the lifecycle, e.g. `2025-11-25` |
213
+ | `MCP-Session-Id` | MUST if the server issued a session id | Sent on all subsequent HTTP requests of this MCP session |
214
+ | `Accept` | MUST | `application/json, text/event-stream` for POST; `text/event-stream` for GET |
215
+ | `Content-Type` | MUST for POST | `application/json` |
216
+ | `Last-Event-ID` | MAY | Used by the client to resume an SSE stream |
217
+
218
+ Session management:
219
+
220
+ - the server MAY issue an `MCP-Session-Id` in the HTTP response to `initialize`;
221
+ - the session id MUST be globally unique, cryptographically strong, and contain only visible ASCII;
222
+ - if the server requires `MCP-Session-Id`, requests without it after initialization must receive HTTP 400;
223
+ - if the session has expired, a request with that session must receive HTTP 404;
224
+ - the session id MUST NOT be used as proof of identity or as a replacement for `Authorization`.
225
+
226
+ CORS / Origin:
227
+
228
+ - the server MUST explicitly configure the list of allowed origins;
229
+ - `*` is forbidden in production;
230
+ - preflight OPTIONS MUST be handled correctly;
231
+ - the server MUST validate `Origin` on HTTP / Streamable HTTP requests if the header is present;
232
+ - on an invalid `Origin`, the server MUST return HTTP 403;
233
+ - local HTTP MCP servers SHOULD bind to `127.0.0.1` rather than `0.0.0.0`.
234
+
235
+ ## 7. Authentication and authorization
236
+
237
+ ### 7.1. General rules
238
+
239
+ | Requirement | Level |
240
+ | --------------------------------------------------------- | ----- |
241
+ | HTTP / Streamable HTTP without authentication | FORBIDDEN for internal servers |
242
+ | Passing secrets in the query string | FORBIDDEN |
243
+ | Passing secrets in logs / traces | FORBIDDEN |
244
+ | Anonymous access to `tools/list`, `prompts/list` | MAY (if explicitly decided) |
245
+ | Authentication on `tools/call`, `prompts/get`, `resources/read` | MUST |
246
+
247
+ ### 7.2. Supported corporate schemes
248
+
249
+ | Scheme | Use | Level |
250
+ | ----------------- | ------------------------------------- | ----- |
251
+ | `Bearer` (JWT) | Primary for service-to-service and user-context | MUST support |
252
+ | `Bearer` (opaque) | Long-lived server tokens from the secret manager | MAY |
253
+ | `Basic` | Service scenarios and admin endpoints only | MAY |
254
+ | Custom | Only with explicit documentation in the README + the `use://http-headers` resource | MAY |
255
+
256
+ Header:
257
+
258
+ ```http
259
+ Authorization: Bearer <token>
260
+ ```
261
+
262
+ The detailed corporate JWT profile is in [Appendix A](#appendix-a-auth-profile).
263
+
264
+ ### 7.3. Compatibility with OAuth MCP authorization
265
+
266
+ If the MCP server is published for generic MCP clients and uses authorization, it SHOULD follow the common
267
+ MCP authorization profile:
268
+
269
+ - the MCP server acts as an OAuth 2.1 resource server;
270
+ - the server publishes OAuth 2.0 Protected Resource Metadata
271
+ (`/.well-known/oauth-protected-resource`);
272
+ - the authorization server publishes OAuth 2.0 Authorization Server Metadata
273
+ (`/.well-known/oauth-authorization-server`);
274
+ - the HTTP 401 response contains `WWW-Authenticate` pointing to the resource metadata;
275
+ - the client uses the `resource` parameter on authorization/token requests;
276
+ - the server validates that the access token was issued specifically for this MCP server audience;
277
+ - token passthrough is forbidden: the MCP server MUST NOT forward downstream the same access token it
278
+ received from the MCP client if the downstream is a separate resource server.
279
+
280
+ Internal Avatar servers MAY use the corporate JWT / opaque token profile without full OAuth discovery if
281
+ this is explicitly stated in the README and `use://auth`.
282
+
283
+ ### 7.4. Authentication responses
284
+
285
+ | Situation | HTTP | Header |
286
+ | ---------------------------------- | ---- | ----------------------------------------------- |
287
+ | Token missing | 401 | `WWW-Authenticate: Bearer realm="<service>"` or an OAuth resource metadata challenge |
288
+ | Token invalid / expired | 401 | `WWW-Authenticate: Bearer error="invalid_token"` |
289
+ | Token valid, no rights for operation | 403 | — |
290
+
291
+ Authentication errors at the HTTP layer are returned as HTTP 401/403. If the error is already inside
292
+ JSON-RPC processing, the server MAY return a JSON-RPC error in the §13 format, but it must not override the
293
+ standard JSON-RPC codes for transport auth.
294
+
295
+ ### 7.5. Authorization
296
+
297
+ The server MUST support at least **boolean authorization** ("allowed / not allowed"). Fine-grained
298
+ authorization (per-tool, per-resource) is SHOULD.
299
+
300
+ If the server uses roles / scopes from a JWT, the list of claims used MUST be documented in
301
+ `use://http-headers` or a separate `use://auth` resource.
302
+
303
+ ## 8. MCP methods and lifecycle
304
+
305
+ ### 8.1. Lifecycle
306
+
307
+ The MCP lifecycle MUST be executed in the following order:
308
+
309
+ 1. The client sends `initialize` with `protocolVersion`, `capabilities`, `clientInfo`.
310
+ 2. The server responds with `initialize.result` with `protocolVersion`, `capabilities`, `serverInfo`.
311
+ 3. The client sends `notifications/initialized`.
312
+ 4. After that, both parties exchange normal MCP requests/notifications only within the negotiated
313
+ capabilities.
314
+
315
+ Until initialization completes, both client and server SHOULD NOT send normal requests, except `ping` and
316
+ allowed service notifications.
317
+
318
+ ### 8.2. Capability negotiation
319
+
320
+ The server MUST declare the capabilities it actually supports:
321
+
322
+ | Capability | Level | Purpose |
323
+ | ---------- | ----- | ------- |
324
+ | `tools` | MUST if the server publishes tools | Callable tools |
325
+ | `prompts` | MAY | Prompt templates |
326
+ | `resources` | MAY | Readable resources |
327
+ | `logging` | SHOULD | Structured log messages |
328
+ | `completions` | MAY | Autocomplete for arguments |
329
+ | `tasks` | MAY | Task-augmented execution, MCP 2025-11-25 |
330
+ | `experimental` | MAY | Non-standard extensions |
331
+
332
+ If a capability is not declared and negotiated, the server MUST NOT require the client to support the
333
+ corresponding methods.
334
+
335
+ ### 8.3. MCP methods
336
+
337
+ The server MUST accept the standard MCP methods within the declared capabilities:
338
+
339
+ | Method | Level | Purpose |
340
+ | ----------------- | -------------------------------- | ----------------------------------- |
341
+ | `initialize` | MUST | Handshake, version, capabilities |
342
+ | `notifications/initialized` | MUST accept after `initialize` | Completes initialization |
343
+ | `tools/list` | MUST if the server publishes tools | List of tools |
344
+ | `tools/call` | MUST if the server publishes tools | Tool invocation |
345
+ | `prompts/list` | MUST if the server publishes prompts | List of prompts |
346
+ | `prompts/get` | MUST if the server publishes prompts | Get a prompt |
347
+ | `resources/list` | MUST if the server publishes resources | List of resources |
348
+ | `resources/read` | MUST if the server publishes resources | Read a resource |
349
+ | `resources/templates/list` | MAY if the server publishes template resources | List of resource templates |
350
+ | `resources/subscribe` | MAY if subscriptions are supported | Subscribe to resource changes |
351
+ | `ping` | SHOULD | Keepalive |
352
+
353
+ The server MUST NOT:
354
+
355
+ - register custom method names instead of the standard MCP ones;
356
+ - silently ignore an unknown method — it must return `-32601 Method not found`;
357
+ - use capability-specific methods without declaring the corresponding capability.
358
+
359
+ ### 8.4. Pagination
360
+
361
+ The `tools/list`, `prompts/list`, `resources/list`, and `resources/templates/list` methods MUST support MCP
362
+ pagination if the potential list can be large.
363
+
364
+ Rules:
365
+
366
+ - the request MAY contain `params.cursor`;
367
+ - the response MAY contain `nextCursor`;
368
+ - the client SHOULD keep reading while `nextCursor` is present;
369
+ - the server MUST NOT change the order of items between pages within a single listing without a reason.
370
+
371
+ ### 8.5. Cancellation
372
+
373
+ MCP supports cancellation of in-progress requests via `notifications/cancelled`.
374
+
375
+ The server SHOULD:
376
+
377
+ - accept `notifications/cancelled` for long-running operations;
378
+ - stop executing the cancelled request when it is safe to do so;
379
+ - release resources;
380
+ - log the reason without user secrets;
381
+ - not send a response for a request whose processing was cancelled before completion.
382
+
383
+ The client MUST NOT cancel `initialize`.
384
+
385
+ ### 8.6. Progress
386
+
387
+ For long-running operations, the server MAY send `notifications/progress` if the request contains
388
+ `_meta.progressToken`.
389
+
390
+ Rules:
391
+
392
+ - `progressToken` must reference only an active request;
393
+ - the `progress` value must increase monotonically;
394
+ - `total` and `message` are optional;
395
+ - progress notifications must stop after the request completes;
396
+ - the rate of progress events must be limited so as not to overload the client.
397
+
398
+ ### 8.7. Tasks
399
+
400
+ MCP 2025-11-25 introduces task-augmented execution as an additional capability. The server MAY declare the
401
+ `tasks` capability and `execution.taskSupport` on individual tools if it supports long-lived or managed
402
+ tasks.
403
+
404
+ If tasks are not supported, the server MUST NOT declare the `tasks` capability and must use the regular
405
+ `tools/call` flow.
406
+
407
+ ## 9. Tools: external contract
408
+
409
+ ### 9.1. Tool declaration
410
+
411
+ Each tool in `tools/list` MUST contain:
412
+
413
+ | Field | Type | Level | Requirement |
414
+ | ------------- | ------ | ------- | --------------------------------------- |
415
+ | `name` | string | MUST | `^[a-z][a-z0-9_]{1,63}$`, snake_case, English. This corporate constraint is stricter than common MCP. |
416
+ | `description` | string | MUST | Concise description + constraints + side effects + dangerous actions |
417
+ | `inputSchema` | object | MUST | Valid JSON Schema 2020-12 by default |
418
+ | `title` | string | SHOULD | Human-readable tool name for UI |
419
+ | `outputSchema` | object | SHOULD if the tool returns `structuredContent` | JSON Schema of the result |
420
+ | `annotations` | object | MAY | Hints to the client (`readOnlyHint`, etc.) |
421
+ | `icons` | array | MAY | Icons for UI |
422
+ | `execution` | object | MAY | Execution metadata, including `taskSupport` |
423
+
424
+ The snake_case corporate rule is preserved deliberately. It narrows common MCP 2025-11-25, which also
425
+ allows `-`, `.`, uppercase, and camelCase.
426
+
427
+ ### 9.2. `inputSchema` requirements
428
+
429
+ - JSON Schema 2020-12 is used by default.
430
+ - If draft-07 is used, the `$schema` field MUST be specified explicitly.
431
+ - `inputSchema` MUST be a valid JSON Schema object, not `null`.
432
+ - `type: "object"` at the top level — SHOULD.
433
+ - explicit `properties` — SHOULD;
434
+ - explicit `required` — SHOULD, even if empty;
435
+ - `additionalProperties: false` — SHOULD;
436
+ - a `description` for each field — SHOULD.
437
+
438
+ Recommended schema for a tool without parameters:
439
+
440
+ ```json
441
+ {
442
+ "type": "object",
443
+ "additionalProperties": false
444
+ }
445
+ ```
446
+
447
+ ### 9.3. Side effects and risk level
448
+
449
+ This section is a corporate requirement on top of common MCP.
450
+
451
+ | Requirement | Level |
452
+ | --------------------------------------------------------------------- | ----- |
453
+ | A mutating tool MUST explicitly state its side effects in `description`. | MUST |
454
+ | A mutating tool MUST declare a risk level (for example `low` / `medium` / `high`). | MUST |
455
+ | Domain errors that the model can correct are returned as `result.isError=true`. | SHOULD |
456
+
457
+ The risk level MAY be expressed through the standard `annotations` field (for example `readOnlyHint`,
458
+ `destructiveHint`, `idempotentHint`) and MUST additionally be stated in human-readable form in
459
+ `description` so that a routing agent can reason about it without parsing annotations.
460
+
461
+ For tools with external side effects, the following MUST also be documented (in `description`, the README,
462
+ or a dedicated resource):
463
+
464
+ - an idempotency key, or the reason idempotency is absent;
465
+ - the retry policy;
466
+ - the timeout behavior;
467
+ - the audit event emitted by the operation;
468
+ - the approval requirement for risky actions.
469
+
470
+ A read-only tool SHOULD set `readOnlyHint: true` so that clients can treat it as safe to call without
471
+ confirmation.
472
+
473
+ ### 9.4. `tools/call` behavior
474
+
475
+ | Situation | Response |
476
+ | --------------------------------------- | ------------------------------------------- |
477
+ | Malformed JSON-RPC or invalid `tools/call.params` structure | JSON-RPC error `-32602 Invalid params` |
478
+ | Unknown `params.name` | JSON-RPC error `-32602 Invalid params` with the safe message `Unknown tool` |
479
+ | Business logic / domain validation error the model can fix | `result.isError=true` with actionable `content` |
480
+ | Internal JSON-RPC layer error | JSON-RPC error `-32603 Internal error` without a stacktrace |
481
+ | Success | `result` with `content`, `structuredContent`, or both formats |
482
+
483
+ The server MUST validate `arguments` against `inputSchema` before reaching the domain. Errors that relate
484
+ to the shape of the JSON-RPC request are returned as a JSON-RPC error. Tool execution errors and domain
485
+ errors are returned as a tool execution result with `isError: true` if that helps the model adjust the
486
+ request.
487
+
488
+ Example of a tool execution error:
489
+
490
+ ```json
491
+ {
492
+ "jsonrpc": "2.0",
493
+ "id": 4,
494
+ "result": {
495
+ "content": [
496
+ { "type": "text", "text": "Invalid date: value must be in the future." }
497
+ ],
498
+ "isError": true
499
+ }
500
+ }
501
+ ```
502
+
503
+ ### 9.5. Structured output
504
+
505
+ If a tool declares `outputSchema`, the server MUST return `structuredContent` that conforms to that schema.
506
+
507
+ For backward compatibility, a tool returning `structuredContent` SHOULD also return the serialized JSON in
508
+ `content` as `TextContent`.
509
+
510
+ ## 10. Prompts: external contract
511
+
512
+ ### 10.1. Prompt support
513
+
514
+ Prompts are an optional MCP capability. The server MAY publish no prompts. If the server publishes prompts,
515
+ it MUST declare the `prompts` capability and implement `prompts/list` and `prompts/get`.
516
+
517
+ ### 10.2. Recommended Avatar profile prompts
518
+
519
+ For servers that participate in agent routing, the following SHOULD be published:
520
+
521
+ | Name | Level | Purpose |
522
+ | --------------- | ------- | ------------------------------------------- |
523
+ | `agent_brief` | SHOULD | Short description for agent routing (level 1) |
524
+ | `agent_prompt` | SHOULD | Full operating instructions (level 2) |
525
+
526
+ These prompts are an Avatar-profile corporate recommendation and are not mandatory names of common MCP.
527
+
528
+ ### 10.3. `agent_brief` content
529
+
530
+ SHOULD describe:
531
+
532
+ - the server's domain;
533
+ - when to select this server;
534
+ - when **not** to select it;
535
+ - key constraints (read-only, data domain, etc.).
536
+
537
+ Size — SHOULD NOT exceed 2 KB of text.
538
+
539
+ ### 10.4. `agent_prompt` content
540
+
541
+ SHOULD contain:
542
+
543
+ - instructions for using each tool;
544
+ - domain and security constraints;
545
+ - the expected format of the agent's responses;
546
+ - examples (SHOULD).
547
+
548
+ ### 10.5. Parameterized prompts
549
+
550
+ If a prompt accepts arguments, they MUST be described in `prompts/list` via the standard MCP `arguments`
551
+ field.
552
+
553
+ Important: `prompts/list.result.prompts[].arguments` is not a full JSON Schema. It is an array of
554
+ descriptors of the form:
555
+
556
+ ```json
557
+ [
558
+ {
559
+ "name": "code",
560
+ "description": "The code to review",
561
+ "required": true
562
+ }
563
+ ]
564
+ ```
565
+
566
+ Complex prompt-argument validation rules SHOULD be documented in `description`, the README, or a separate
567
+ resource.
568
+
569
+ A prompt definition MAY contain `title`, `description`, `icons`, and `arguments` per MCP 2025-11-25.
570
+
571
+ ## 11. Resources: external contract
572
+
573
+ ### 11.1. URI schemes
574
+
575
+ Two classes of schemes are used.
576
+
577
+ **1. Service-specific scheme (MUST).** For resources belonging to a specific server, a unique scheme is
578
+ used that matches the service name in the registry:
579
+
580
+ ```
581
+ <service-name>://<path>
582
+ ```
583
+
584
+ Example: `staff://agent/brief`. The server MUST respond only to its own scheme and MUST NOT register
585
+ others.
586
+
587
+ **2. Reserved cross-service schemes (standard for the Avatar profile).** This standard reserves the
588
+ following global schemes for uniform meta-information; their semantics are fixed and identical across
589
+ internal servers:
590
+
591
+ | Scheme | Purpose |
592
+ | ------------ | --------------------------------------------------------- |
593
+ | `use://` | Instructions for using the server (headers, auth, etc.) |
594
+ | `project://` | Server meta-information (version, name, owner) |
595
+ | `doc://` | Server documentation (README, etc.) |
596
+
597
+ The server MUST implement those `use://` / `project://` / `doc://` resources required by §11.2. Inventing
598
+ your own paths under these schemes beyond this standard is FORBIDDEN.
599
+
600
+ ### 11.2. Recommended minimum resources
601
+
602
+ | URI | Level | Purpose |
603
+ | -------------------------------- | ------- | --------------------------------------------- |
604
+ | `<service-name>://agent/brief` | SHOULD | Mirror of the `agent_brief` prompt |
605
+ | `<service-name>://agent/prompt` | SHOULD | Mirror of the `agent_prompt` prompt |
606
+ | `use://http-headers` | MUST if there are non-standard headers | Description of all expected HTTP headers |
607
+ | `use://auth` | SHOULD | Description of the authentication scheme and claims |
608
+ | `project://version` | SHOULD | Current server version |
609
+ | `doc://readme` | MAY | Mirror of the README |
610
+
611
+ ### 11.3. Resource definition format
612
+
613
+ An item in `resources/list.result.resources[]` SHOULD describe:
614
+
615
+ | Field | Level | Purpose |
616
+ | ----- | ----- | ------- |
617
+ | `uri` | MUST | Unique resource URI |
618
+ | `name` | MUST | Resource name |
619
+ | `title` | MAY | Human-readable title for UI |
620
+ | `description` | MAY | Description |
621
+ | `mimeType` | MAY | MIME type |
622
+ | `size` | MAY | Size in bytes |
623
+ | `icons` | MAY | Icons for UI |
624
+
625
+ ### 11.4. `resources/read` format
626
+
627
+ `resources/read` MUST return content inside `result.contents[]`. Each content item MUST contain `uri`,
628
+ `mimeType`, and one of the fields `text` or `blob`.
629
+
630
+ Example:
631
+
632
+ ```json
633
+ {
634
+ "jsonrpc": "2.0",
635
+ "id": 2,
636
+ "result": {
637
+ "contents": [
638
+ {
639
+ "uri": "doc://readme",
640
+ "mimeType": "text/markdown",
641
+ "text": "# README"
642
+ }
643
+ ]
644
+ }
645
+ }
646
+ ```
647
+
648
+ ### 11.5. Additional resource capabilities
649
+
650
+ The server MAY support resource templates:
651
+
652
+ - declare the `resources` capability;
653
+ - implement `resources/templates/list`;
654
+ - return `resourceTemplates[]` with `uriTemplate`, `name`, `title`, `description`, `mimeType`, `icons`.
655
+
656
+ The server MAY support subscriptions:
657
+
658
+ - declare `resources.subscribe=true`;
659
+ - accept `resources/subscribe`;
660
+ - send `notifications/resources/updated` when a resource changes;
661
+ - send `notifications/resources/list_changed` if `resources.listChanged=true` is declared.
662
+
663
+ ## 12. Result format
664
+
665
+ ### 12.1. Allowed tool result formats
666
+
667
+ A tool result MAY contain one or both formats:
668
+
669
+ | Format | When to use |
670
+ | ------------------- | ------------------------------------------- |
671
+ | `content` | Human-readable responses, markdown, text, image/audio/resource content |
672
+ | `structuredContent` | Machine-readable JSON data with a fixed schema |
673
+
674
+ For a specific tool, the format must be deterministic and documented.
675
+
676
+ ### 12.2. Requirements
677
+
678
+ - if the response is truncated by limits, the truncation flag MUST be visible to the client (as text in
679
+ `content` or a field in `structuredContent`);
680
+ - personal / sensitive data MUST be protected per the domain policy (masking, filtering);
681
+ - binary data is transmitted as `blob` with the correct `mimeType`;
682
+ - if `structuredContent` and `outputSchema` are used, the result MUST conform to `outputSchema`;
683
+ - for backward compatibility, `structuredContent` SHOULD be duplicated in `content` as serialized JSON
684
+ text.
685
+
686
+ ### 12.3. Text response example
687
+
688
+ ```json
689
+ {
690
+ "content": [
691
+ { "type": "text", "text": "..." }
692
+ ]
693
+ }
694
+ ```
695
+
696
+ ### 12.4. Structured response example
697
+
698
+ ```json
699
+ {
700
+ "content": [
701
+ { "type": "text", "text": "{\"rows\":[],\"truncated\":false,\"rowCount\":0}" }
702
+ ],
703
+ "structuredContent": {
704
+ "rows": [],
705
+ "truncated": false,
706
+ "rowCount": 0
707
+ }
708
+ }
709
+ ```
710
+
711
+ ## 13. Error format
712
+
713
+ ### 13.1. Protocol errors and tool execution errors
714
+
715
+ MCP uses two types of errors:
716
+
717
+ | Type | When to use | Format |
718
+ | ---- | ----------- | ------ |
719
+ | Protocol error | Invalid JSON-RPC, unknown method, malformed params, transport/protocol layer error | JSON-RPC error object |
720
+ | Tool execution error | The tool was called correctly, but the domain operation failed or the input can be fixed | `result.isError=true` |
721
+
722
+ Protocol error example:
723
+
724
+ ```json
725
+ {
726
+ "jsonrpc": "2.0",
727
+ "id": "<request-id>",
728
+ "error": {
729
+ "code": -32602,
730
+ "message": "Invalid params",
731
+ "data": { "field": "name", "reason": "required" }
732
+ }
733
+ }
734
+ ```
735
+
736
+ ### 13.2. Classes of protocol errors
737
+
738
+ The full list is in [Appendix B](#appendix-b-error-codes).
739
+
740
+ | Class | JSON-RPC code | HTTP |
741
+ | -------------------- | ----------------- | ------ |
742
+ | Parse error | -32700 | 400 |
743
+ | Invalid request | -32600 | 400 |
744
+ | Method not found | -32601 | 404 |
745
+ | Invalid params | -32602 | 400 |
746
+ | Internal error | -32603 | 500 |
747
+ | Server error | -32000 | 500 |
748
+ | Resource not found | -32002 | 404 |
749
+ | Rate limited | -32003 | 429 |
750
+ | Timeout | -32004 | 504 |
751
+ | Payload too large | -32005 | 413 |
752
+ | Upstream unavailable | -32006 | 503 |
753
+ | Conflict | -32007 | 409 |
754
+
755
+ Auth failures at the HTTP layer are returned via HTTP 401/403 and `WWW-Authenticate`, not by overriding the
756
+ standard JSON-RPC codes.
757
+
758
+ ### 13.3. Prohibitions
759
+
760
+ An error returned externally MUST NOT contain:
761
+
762
+ - a stack trace;
763
+ - secrets, tokens, passwords, connection strings;
764
+ - internal filesystem paths;
765
+ - raw SQL/expression text with user data;
766
+ - internal service names that are not part of the public contract.
767
+
768
+ ## 14. Limits and protection
769
+
770
+ Each server MUST document and enforce:
771
+
772
+ | Limit | Default | Level |
773
+ | --------------------------- | ------------- | ----- |
774
+ | Input payload size | 1 MB | MUST |
775
+ | Tool result size | 10 MB | MUST |
776
+ | Tool call timeout | 30 seconds | MUST |
777
+ | Rate limit per token | service-defined | SHOULD |
778
+ | Max concurrent calls per token | service-defined | SHOULD |
779
+
780
+ On exceeding a limit:
781
+
782
+ - payload too large → `-32005` / HTTP 413;
783
+ - result too large → truncation with an explicit flag;
784
+ - timeout → `-32004` / HTTP 504;
785
+ - rate limit → `-32003` / HTTP 429 with the `Retry-After` header.
786
+
787
+ On timeout, the sender SHOULD send `notifications/cancelled` and stop waiting for the response if applicable
788
+ to the current transport/session.
789
+
790
+ ## 15. Observability
791
+
792
+ ### 15.1. Correlation
793
+
794
+ For servers with the HTTP / Streamable HTTP transport, the server MUST support propagating identifiers via
795
+ HTTP headers:
796
+
797
+ | Header | Level | Behavior |
798
+ | ---------------- | ----- | ------------------------------------------ |
799
+ | `X-Request-Id` | MUST | Accept; generate if absent; return in the response |
800
+ | `traceparent` | SHOULD | Accept the W3C trace context |
801
+ | `tracestate` | MAY | Propagate further |
802
+ | `MCP-Session-Id` | MAY | Use to correlate MCP session events, but not as identity |
803
+
804
+ For the stdio transport, the server MUST generate its own request id per JSON-RPC call and use it in logs
805
+ for correlation.
806
+
807
+ ### 15.2. Logging
808
+
809
+ The server MUST log:
810
+
811
+ - the fact of a tool call: name, request id, duration, status (ok / error class);
812
+ - auth-failure facts: reason, request id;
813
+ - internal errors with full context — **only to internal logs**, never externally.
814
+
815
+ The server MUST NOT log:
816
+
817
+ - `arguments` values containing personal data, without masking;
818
+ - tokens, passwords, `Authorization` headers.
819
+
820
+ ### 15.3. Metrics
821
+
822
+ SHOULD expose:
823
+
824
+ - a call counter by tool and status;
825
+ - a call-duration histogram;
826
+ - an auth-failures counter;
827
+ - a rate-limit events counter.
828
+
829
+ ## 16. Health and readiness
830
+
831
+ ### 16.1. `/health` (liveness)
832
+
833
+ | Property | Requirement |
834
+ | ----------------- | ----------------------------------- |
835
+ | Method | GET |
836
+ | Authentication | NOT required |
837
+ | Body | JSON |
838
+ | HTTP 200 | service is alive |
839
+ | HTTP 503 | service cannot serve requests |
840
+
841
+ Minimal body:
842
+
843
+ ```json
844
+ {
845
+ "status": "ok",
846
+ "version": "1.2.3",
847
+ "uptime": 3600
848
+ }
849
+ ```
850
+
851
+ ### 16.2. `/ready` (readiness)
852
+
853
+ SHOULD. Returns 200 only when the server is ready to accept `tools/call` (including dependency readiness:
854
+ DB, secret store, JWKS).
855
+
856
+ ```json
857
+ {
858
+ "status": "ready",
859
+ "checks": {
860
+ "db": "ok",
861
+ "jwks": "ok"
862
+ }
863
+ }
864
+ ```
865
+
866
+ ### 16.3. Prohibitions
867
+
868
+ The `/health` and `/ready` responses MUST NOT include:
869
+
870
+ - secrets;
871
+ - connection strings;
872
+ - full dependency error messages (status only).
873
+
874
+ ## 17. Contract stability and deprecation
875
+
876
+ ### 17.1. What is part of the public contract
877
+
878
+ | Element | Stability |
879
+ | -------------------------------- | ------------- |
880
+ | Supported transports | MAJOR |
881
+ | HTTP endpoints (`/mcp`, `/health`, legacy `/sse`) | MAJOR |
882
+ | Authentication scheme | MAJOR |
883
+ | List of tools (names) | MAJOR |
884
+ | Tool `inputSchema` (required fields) | MAJOR |
885
+ | Tool `outputSchema` | MAJOR if published |
886
+ | Result format of each tool | MAJOR |
887
+ | Prompt names | MAJOR |
888
+ | URI scheme and base resources | MAJOR |
889
+ | Error codes | MAJOR |
890
+ | Adding a new tool / prompt / resource | MINOR |
891
+ | Adding an optional field | MINOR |
892
+ | Extending a `description` | PATCH |
893
+
894
+ ### 17.2. Deprecation process
895
+
896
+ 1. The `description` of the tool/prompt/resource gets a `[DEPRECATED]` prefix and a support deadline.
897
+ 2. It is announced in the server's CHANGELOG.
898
+ 3. The minimum period before removal is **2 MINOR versions** or **3 months**, whichever is longer.
899
+ 4. Known consumers are notified (via the owner team).
900
+ 5. After the deadline, removal happens in the next MAJOR.
901
+
902
+ ### 17.3. CHANGELOG
903
+
904
+ The server MUST maintain a `CHANGELOG.md` in the Keep a Changelog format.
905
+
906
+ ## 18. Compliance checklist
907
+
908
+ Minimal acceptance checklist. All MUST items are mandatory to pass review.
909
+
910
+ ### Transport and HTTP
911
+
912
+ - [ ] at least one transport from {stdio, streamable_http, legacy_http_sse} is supported
913
+ - [ ] for Streamable HTTP, `POST /mcp` is implemented
914
+ - [ ] `POST /mcp` accepts `Accept: application/json, text/event-stream`
915
+ - [ ] `MCP-Protocol-Version` is supported after initialization
916
+ - [ ] if sessions are used, `MCP-Session-Id` is supported
917
+ - [ ] `GET /health` is implemented for HTTP
918
+ - [ ] CORS is configured explicitly, without `*` in production
919
+ - [ ] `Origin` is validated; an invalid origin returns 403
920
+ - [ ] the maximum payload size is documented
921
+
922
+ ### Authentication
923
+
924
+ - [ ] HTTP / Streamable HTTP requires authentication on `tools/call`
925
+ - [ ] `Authorization: Bearer <token>` is supported
926
+ - [ ] JWT is validated by issuer / audience / exp (see Appendix A)
927
+ - [ ] 401 contains a correct `WWW-Authenticate`
928
+ - [ ] for generic MCP clients, OAuth discovery is described, or the server is explicitly marked internal-only
929
+ - [ ] token passthrough is forbidden
930
+ - [ ] secrets are not passed in the query / logs
931
+
932
+ ### MCP lifecycle and methods
933
+
934
+ - [ ] `initialize` responds with the protocol version, capabilities, and `serverInfo`
935
+ - [ ] the server accepts `notifications/initialized`
936
+ - [ ] only negotiated capabilities are used
937
+ - [ ] `tools/list` and `tools/call` work if the `tools` capability is declared
938
+ - [ ] `prompts/list` and `prompts/get` work if the `prompts` capability is declared
939
+ - [ ] `resources/list` and `resources/read` work if the `resources` capability is declared
940
+ - [ ] an unknown method → `-32601`
941
+
942
+ ### Tools
943
+
944
+ - [ ] all tools have `name`, `description`, `inputSchema`
945
+ - [ ] names are snake_case and English
946
+ - [ ] `inputSchema` is compatible with JSON Schema 2020-12 or explicitly specifies `$schema`
947
+ - [ ] `arguments` are validated against the schema
948
+ - [ ] mutating tools state their side effects and risk level
949
+ - [ ] tools with external side effects document idempotency, retry, timeout, audit, and approval
950
+ - [ ] business/tool execution errors are returned via `result.isError=true`
951
+ - [ ] the result format is deterministic
952
+
953
+ ### Prompts
954
+
955
+ - [ ] prompts are declared only if the `prompts` capability exists
956
+ - [ ] if the server participates in agent routing, `agent_brief` and `agent_prompt` are published, or the deviation is explained in the README
957
+ - [ ] prompt arguments are described via the standard MCP `arguments[]`, not as an `inputSchema`
958
+
959
+ ### Resources
960
+
961
+ - [ ] if there are non-standard headers, `use://http-headers` is published
962
+ - [ ] URIs use scheme = service name or the corporate schemes `use://`, `project://`, `doc://`
963
+ - [ ] `resources/read` returns `result.contents[]` with `uri`, `mimeType`, `text` or `blob`
964
+ - [ ] `resources/templates/list` and subscriptions are implemented only if the corresponding capabilities are declared
965
+
966
+ ### Errors and limits
967
+
968
+ - [ ] protocol errors are returned in the JSON-RPC format
969
+ - [ ] tool execution errors are returned via `isError=true`
970
+ - [ ] error codes match Appendix B
971
+ - [ ] timeout, rate limit, payload limit are implemented and documented
972
+ - [ ] errors do not contain a stacktrace or secrets
973
+
974
+ ### Observability
975
+
976
+ - [ ] `X-Request-Id` is supported
977
+ - [ ] `traceparent` is accepted if the W3C trace context is used
978
+ - [ ] there is structured logging of calls
979
+ - [ ] logs do not contain tokens and PII without masking
980
+
981
+ ### Documentation and contract
982
+
983
+ - [ ] there is a README describing the public contract
984
+ - [ ] there is a CHANGELOG.md
985
+ - [ ] semver is followed
986
+ - [ ] the version is available in `/health` and `initialize.result.serverInfo.version`
987
+ - [ ] the `project://version` resource is implemented, or it is explicitly acknowledged as optional for the server
988
+
989
+ ---
990
+
991
+ ## Appendix A. Auth profile
992
+
993
+ ### A.1. JWT — the mandatory profile for internal servers
994
+
995
+ | Parameter | Requirement |
996
+ | ----------------- | ------------------------------------------------ |
997
+ | Signing algorithm | RS256 or ES256 (HS256 — local development only) |
998
+ | Key source | Corporate JWKS endpoint |
999
+ | JWKS cache | TTL ≤ 10 minutes |
1000
+ | `exp` validation | MUST |
1001
+ | `nbf` validation | MUST if present |
1002
+ | `iss` validation | MUST, value from config |
1003
+ | `aud` validation | MUST, value = server identifier |
1004
+ | Allowed clock skew | ≤ 60 seconds |
1005
+
1006
+ ### A.2. Minimal set of claims
1007
+
1008
+ | Claim | Type | Purpose |
1009
+ | ------- | ------ | --------------------------------------- |
1010
+ | `iss` | string | Issuer (corporate IdP) |
1011
+ | `aud` | string | Target server identifier |
1012
+ | `sub` | string | Subject identifier (user / service) |
1013
+ | `exp` | number | Expiration |
1014
+ | `iat` | number | Issued-at time |
1015
+ | `scope` | string | Space-separated list of scopes (if used) |
1016
+
1017
+ ### A.3. Opaque tokens
1018
+
1019
+ Allowed only if:
1020
+
1021
+ - stored in the corporate secret store;
1022
+ - rotated per company policy;
1023
+ - verified via an introspection endpoint or a built-in whitelist.
1024
+
1025
+ ### A.4. Basic Auth
1026
+
1027
+ - HTTPS only;
1028
+ - admin/service endpoints only;
1029
+ - credentials taken from the secret store, not from code.
1030
+
1031
+ ### A.5. Header examples
1032
+
1033
+ ```http
1034
+ Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
1035
+ MCP-Protocol-Version: 2025-11-25
1036
+ MCP-Session-Id: 1868a90c-7c1e-4f8c-9c19-2d28d9e4f1aa
1037
+ Accept: application/json, text/event-stream
1038
+ X-Request-Id: 6f1c4f0e-2b7a-4f3e-8b7e-1a9b5c2d3e4f
1039
+ traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
1040
+ ```
1041
+
1042
+ ---
1043
+
1044
+ ## Appendix B. Error codes
1045
+
1046
+ ### B.1. JSON-RPC codes
1047
+
1048
+ | Code | Name | HTTP | When |
1049
+ | -------- | ------------------ | ---- | ------------------------------------------- |
1050
+ | -32700 | Parse error | 400 | Invalid JSON |
1051
+ | -32600 | Invalid Request | 400 | Does not conform to JSON-RPC |
1052
+ | -32601 | Method not found | 404 | Unknown MCP method |
1053
+ | -32602 | Invalid params | 400 | Invalid params structure / unknown tool name |
1054
+ | -32603 | Internal error | 500 | Internal error of the JSON-RPC layer |
1055
+
1056
+ ### B.2. Server codes (range -32000…-32099)
1057
+
1058
+ | Code | Name | HTTP | When |
1059
+ | -------- | ------------------ | ---- | ------------------------------------------- |
1060
+ | -32000 | Server error | 500 | Internal server error not related to tool execution |
1061
+ | -32002 | Resource not found | 404 | Resource not found |
1062
+ | -32003 | Rate limited | 429 | Rate limit exceeded; include `Retry-After` |
1063
+ | -32004 | Timeout | 504 | Call timeout exceeded |
1064
+ | -32005 | Payload too large | 413 | Size limit exceeded |
1065
+ | -32006 | Upstream unavailable | 503 | A dependency is unavailable (DB, etc.) |
1066
+ | -32007 | Conflict | 409 | State conflict (if applicable) |
1067
+
1068
+ Auth failures are returned via HTTP 401/403. For insufficient scope/resource access, the server SHOULD use
1069
+ HTTP 403 at the transport layer; if the error relates to a specific resource inside MCP, use a safe
1070
+ protocol error or a tool/resource-specific response without disclosing secrets.
1071
+
1072
+ ### B.3. `error.data` structure
1073
+
1074
+ `error.data` SHOULD contain the fields:
1075
+
1076
+ | Field | Type | Purpose |
1077
+ | ---------- | ------ | ------------------------------------------- |
1078
+ | `requestId`| string | Request correlation id |
1079
+ | `field` | string | Field name for validation errors |
1080
+ | `reason` | string | Machine-readable reason (`required`, `format`, `range`, etc.) |
1081
+ | `retryAfter` | number | Seconds until retry (for -32003) |
1082
+
1083
+ ### B.4. Forbidden content
1084
+
1085
+ In `message` and `data`, the following is FORBIDDEN:
1086
+
1087
+ - stack traces;
1088
+ - internal paths;
1089
+ - secrets of any kind;
1090
+ - raw user input text with potential PII.
1091
+
1092
+ ---
1093
+
1094
+ ## Appendix C. Input / output summary table
1095
+
1096
+ ### C.1. What the server accepts
1097
+
1098
+ | Source | What | Level |
1099
+ | ----------------------- | ------------------------------------ | ------- |
1100
+ | Transport | stdio / streamable_http / legacy_http_sse | at least one MUST |
1101
+ | HTTP | `POST /mcp`, `GET /health` | MUST for a streamable_http server |
1102
+ | HTTP | `GET /mcp` | MAY for the SSE stream |
1103
+ | HTTP | `GET /sse` | MAY, legacy only |
1104
+ | Header | `Authorization: Bearer <token>` | MUST for HTTP / Streamable HTTP |
1105
+ | Header | `MCP-Protocol-Version` | MUST after `initialize` for HTTP |
1106
+ | Header | `MCP-Session-Id` | MUST if the server issued a session id |
1107
+ | Header | `Accept: application/json, text/event-stream` | MUST for `POST /mcp` |
1108
+ | Header | `X-Request-Id` | MUST accept |
1109
+ | Header | `traceparent` | SHOULD |
1110
+ | MCP method | `initialize` | MUST |
1111
+ | MCP notification | `notifications/initialized` | MUST accept |
1112
+ | MCP method | `tools/list`, `tools/call` | MUST if the `tools` capability exists |
1113
+ | MCP method | `prompts/list`, `prompts/get` | MUST if the `prompts` capability exists |
1114
+ | MCP method | `resources/list`, `resources/read` | MUST if the `resources` capability exists |
1115
+ | MCP method | `resources/templates/list` | MAY |
1116
+ | MCP method | `resources/subscribe` | MAY |
1117
+ | MCP notification | `notifications/cancelled` | SHOULD for long-running operations |
1118
+ | `tools/call.params` | `name`, `arguments` | MUST |
1119
+ | `prompts/get.params` | `name`, `arguments?` | MUST |
1120
+ | `resources/read.params` | `uri` | MUST |
1121
+
1122
+ ### C.2. What the server returns
1123
+
1124
+ | Where | What | Level |
1125
+ | ----------------------- | ------------------------------------ | ------- |
1126
+ | `initialize.result` | `protocolVersion`, `capabilities`, `serverInfo` | MUST |
1127
+ | `tools/list.result` | tools with `name`, `description`, `inputSchema`; SHOULD `title`, MAY `icons`, `outputSchema`, `execution` | MUST if tools exist |
1128
+ | `tools/call.result` | `content`, `structuredContent`, `isError?` | MUST if tools exist |
1129
+ | `prompts/list.result` | prompts; `agent_brief` / `agent_prompt` SHOULD for Avatar routing | MUST if prompts exist |
1130
+ | `prompts/get.result` | `description?`, `messages[]` | MUST if prompts exist |
1131
+ | `resources/list.result` | list of resources with `uri`, `name`, optional `title`, `mimeType`, `icons` | MUST if resources exist |
1132
+ | `resources/read.result` | `contents[]` with `uri`, `mimeType`, `text` or `blob` | MUST if resources exist |
1133
+ | `GET /health` | JSON with `status`, `version`, `uptime` | MUST for HTTP |
1134
+ | `GET /ready` | JSON with `status`, `checks` | SHOULD |
1135
+ | Response header | `X-Request-Id` | MUST |
1136
+ | Response header | `MCP-Session-Id` | MAY on `initialize` |
1137
+ | Response header (401) | `WWW-Authenticate: Bearer ...` or an OAuth resource metadata challenge | MUST |
1138
+ | Response header (429) | `Retry-After` | MUST |
1139
+ | Protocol error | JSON-RPC error object without secrets and stacktraces | MUST |
1140
+ | Tool execution error | `result.isError=true` | MUST for tool domain errors |
1141
+
1142
+ ### C.3. What the server MUST NOT return externally
1143
+
1144
+ - stack traces;
1145
+ - secrets, tokens, passwords, connection strings;
1146
+ - internal paths and service names;
1147
+ - raw SQL / DSL queries with user data;
1148
+ - personal data beyond what the domain allows.