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