Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{
2 lib,
3 stdenv,
4 buildPythonPackage,
5 fetchFromGitHub,
6
7 # build-system
8 hatchling,
9
10 # dependencies
11 anyio,
12 httpx,
13 httpx-sse,
14 jsonschema,
15 pydantic,
16 pydantic-settings,
17 python-multipart,
18 sse-starlette,
19 starlette,
20 uvicorn,
21
22 # optional-dependencies
23 # cli
24 python-dotenv,
25 typer,
26 # rich
27 rich,
28 # ws
29 websockets,
30
31 # tests
32 dirty-equals,
33 inline-snapshot,
34 pytest-asyncio,
35 pytest-examples,
36 pytest-xdist,
37 pytestCheckHook,
38 requests,
39}:
40
41buildPythonPackage rec {
42 pname = "mcp";
43 version = "1.12.4";
44 pyproject = true;
45
46 src = fetchFromGitHub {
47 owner = "modelcontextprotocol";
48 repo = "python-sdk";
49 tag = "v${version}";
50 hash = "sha256-FHVhufv4O7vM/9fNHyDU4L15dNLFMmoVaYd98Iw6l2o=";
51 };
52
53 postPatch = ''
54 substituteInPlace pyproject.toml \
55 --replace-fail ', "uv-dynamic-versioning"' "" \
56 --replace-fail 'dynamic = ["version"]' 'version = "${version}"'
57 ''
58 + lib.optionalString stdenv.buildPlatform.isDarwin ''
59 # time.sleep(0.1) feels a bit optimistic and it has been flaky whilst
60 # testing this on macOS under load.
61 substituteInPlace \
62 "tests/client/test_stdio.py" \
63 "tests/server/fastmcp/test_integration.py" \
64 "tests/shared/test_ws.py" \
65 "tests/shared/test_sse.py" \
66 "tests/shared/test_streamable_http.py" \
67 --replace-fail "time.sleep(0.1)" "time.sleep(1)"
68 '';
69
70 build-system = [ hatchling ];
71
72 pythonRelaxDeps = [
73 "pydantic-settings"
74 ];
75
76 dependencies = [
77 anyio
78 httpx
79 httpx-sse
80 jsonschema
81 pydantic
82 pydantic-settings
83 python-multipart
84 sse-starlette
85 starlette
86 uvicorn
87 ];
88
89 optional-dependencies = {
90 cli = [
91 python-dotenv
92 typer
93 ];
94 rich = [
95 rich
96 ];
97 ws = [
98 websockets
99 ];
100 };
101
102 pythonImportsCheck = [ "mcp" ];
103
104 nativeCheckInputs = [
105 dirty-equals
106 inline-snapshot
107 pytest-asyncio
108 pytest-examples
109 pytest-xdist
110 pytestCheckHook
111 requests
112 ]
113 ++ lib.flatten (lib.attrValues optional-dependencies);
114
115 disabledTests = [
116 # attempts to run the package manager uv
117 "test_command_execution"
118
119 # ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
120 "test_lifespan_cleanup_executed"
121
122 # AssertionError: Child process should be writing
123 "test_basic_child_process_cleanup"
124
125 # AssertionError: parent process should be writing
126 "test_nested_process_tree"
127
128 # AssertionError: Child should be writing
129 "test_early_parent_exit"
130
131 # pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO ...
132 "test_list_tools_returns_all_tools"
133
134 # AssertionError: Server startup marker not created
135 "test_stdin_close_triggers_cleanup"
136
137 # pytest.PytestUnraisableExceptionWarning: Exception ignored in: <function St..
138 "test_resource_template_client_interaction"
139
140 # Flaky: https://github.com/modelcontextprotocol/python-sdk/pull/1171
141 "test_notification_validation_error"
142
143 # Flaky: httpx.ConnectError: All connection attempts failed
144 "test_sse_security_"
145 "test_streamable_http_"
146
147 # This just feels a bit optimistic...
148 # assert duration < 3 * _sleep_time_seconds
149 # AssertionError: assert 0.0733884589999434 < (3 * 0.01)
150 "test_messages_are_executed_concurrently"
151
152 # ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
153 "test_tool_progress"
154 ];
155
156 __darwinAllowLocalNetworking = true;
157
158 meta = {
159 changelog = "https://github.com/modelcontextprotocol/python-sdk/releases/tag/${src.tag}";
160 description = "Official Python SDK for Model Context Protocol servers and clients";
161 homepage = "https://github.com/modelcontextprotocol/python-sdk";
162 license = lib.licenses.mit;
163 maintainers = with lib.maintainers; [
164 bryanhonof
165 josh
166 ];
167 };
168}