Skip to content

Commit da74f4b

Browse files
RahulHereRahulHere
authored andcommitted
Add Python example for create_with_server_id fix (#9)
Land examples/api/create_by_server_id.py, third of the seven create_by_* examples and the first of the four routing variants added in gopher-orch 0.1.23. Direct port of gopher-mcp-js/examples/api/create_by_server_id.ts, which itself ports gopher-orch/examples/sdk/api/create_by_server_id.cc. Behaviour: - Scopes the agent to a single MCP server in the caller's workspace by id. Internally hits the same GET /v1/mcp-servers endpoint as create_with_api_key under the Bearer api key, but adds the "?serverId={id}" routing query so the response carries only the matching server entry. Use this when the api key owns several MCP servers but the agent should bind to exactly one. - Provider defaults to AnthropicProvider; the model comes from the LLM_MODEL env var. Refuses to call the FFI when any of the three required env vars (LLM_MODEL, GOPHER_API_KEY, GOPHER_MCP_SERVER_ID) is still the placeholder, printing a clear error to stderr and exiting 1. - Reads the routing parameter from GOPHER_MCP_SERVER_ID, matching the JS sibling's env-var name so a downstream user can share env across the JS and Python toolchains. Same pattern for the next three routing variants (server_name, gateway_id, gateway_name). - Accepts queries as positional argv with the canned "What time is it in Tokyo?" fallback. try / finally with agent.dispose() so the native handle is always released. Requires the create_with_server_id factory landed earlier in this PR series; against the vendored 0.1.1 dylib the example exits with an AgentError from the null-handle pump because the C symbol is missing. Against a fresh gopher-orch 0.1.23 build the example completes end-to-end. Verified locally: placeholder refusal path exits 1 with a clear diagnostic; syntax check clean; no forbidden tokens.
1 parent c454665 commit da74f4b

1 file changed

Lines changed: 116 additions & 0 deletions

File tree

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env python3
2+
"""
3+
SDK example for GopherAgent.create_with_server_id.
4+
5+
Python port of gopher-mcp-js/examples/api/create_by_server_id.ts, which
6+
itself ports gopher-orch/examples/sdk/api/create_by_server_id.cc.
7+
8+
Scopes a GopherAgent to a single MCP server in the caller's workspace
9+
by id. Internally this hits the same GET /v1/mcp-servers endpoint as
10+
create_with_api_key under the Bearer api key, but adds the
11+
"?serverId={id}" routing query so the response carries only the
12+
matching server entry. Use this when the api key owns several MCP
13+
servers but the agent should bind to exactly one.
14+
15+
Provider defaults to AnthropicProvider; the model is taken from
16+
LLM_MODEL. Override either via env or by editing the constants in
17+
main().
18+
19+
Configuration (env vars):
20+
GOPHER_API_KEY Gopher API key for /v1/mcp-servers
21+
GOPHER_MCP_SERVER_ID MCP server id to scope the agent to
22+
LLM_PROVIDER Optional. Defaults to "AnthropicProvider".
23+
LLM_MODEL Required. Model identifier the provider accepts.
24+
DEBUG When set, ctypes prints library-resolution diagnostics.
25+
26+
Usage:
27+
python3 create_by_server_id.py # built-in query
28+
python3 create_by_server_id.py "query one" "query two" ... # supplied queries
29+
"""
30+
31+
import os
32+
import sys
33+
import traceback
34+
35+
from gopher_mcp_python import GopherAgent
36+
37+
API_KEY_PLACEHOLDER = "{YOUR_GOPHER_API_KEY}"
38+
SERVER_ID_PLACEHOLDER = "{YOUR_MCP_SERVER_ID}"
39+
MODEL_PLACEHOLDER = "{YOUR_LLM_MODEL}"
40+
41+
42+
def env_or(name: str, fallback: str) -> str:
43+
"""Return os.environ[name] if non-empty, otherwise fallback."""
44+
value = os.environ.get(name, "")
45+
return value if value else fallback
46+
47+
48+
def main() -> None:
49+
print("=== GopherAgent.create_with_server_id example ===")
50+
print(f"Usage: python3 {sys.argv[0]} [query1] [query2] ...")
51+
print(
52+
"Env: GOPHER_API_KEY GOPHER_MCP_SERVER_ID LLM_PROVIDER LLM_MODEL DEBUG"
53+
)
54+
print("")
55+
56+
queries = sys.argv[1:] if len(sys.argv) > 1 else ["What time is it in Tokyo?"]
57+
58+
provider = env_or("LLM_PROVIDER", "AnthropicProvider")
59+
model = env_or("LLM_MODEL", MODEL_PLACEHOLDER)
60+
api_key = env_or("GOPHER_API_KEY", API_KEY_PLACEHOLDER)
61+
server_id = env_or("GOPHER_MCP_SERVER_ID", SERVER_ID_PLACEHOLDER)
62+
63+
print(f"Provider: {provider}")
64+
model_label = (
65+
f"{model} (set LLM_MODEL)" if model == MODEL_PLACEHOLDER else model
66+
)
67+
print(f"Model: {model_label}")
68+
api_key_label = (
69+
f"{api_key} (set GOPHER_API_KEY)"
70+
if api_key == API_KEY_PLACEHOLDER
71+
else "<set via GOPHER_API_KEY>"
72+
)
73+
print(f"API key: {api_key_label}")
74+
server_id_label = (
75+
f"{server_id} (set GOPHER_MCP_SERVER_ID)"
76+
if server_id == SERVER_ID_PLACEHOLDER
77+
else server_id
78+
)
79+
print(f"MCP server id: {server_id_label}")
80+
print(f"Queries: {len(queries)}")
81+
82+
if (
83+
model == MODEL_PLACEHOLDER
84+
or api_key == API_KEY_PLACEHOLDER
85+
or server_id == SERVER_ID_PLACEHOLDER
86+
):
87+
print(
88+
"\nError: LLM_MODEL, GOPHER_API_KEY, and GOPHER_MCP_SERVER_ID "
89+
"must all be set.",
90+
file=sys.stderr,
91+
)
92+
sys.exit(1)
93+
94+
print("\nCreating agent via GopherAgent.create_with_server_id...")
95+
agent = GopherAgent.create_with_server_id(provider, model, api_key, server_id)
96+
print("Agent created successfully!")
97+
98+
try:
99+
for i, query in enumerate(queries):
100+
print(f"\nQuery {i + 1}: {query}")
101+
answer = agent.run(query)
102+
print(f"\nAgent Response {i + 1}:")
103+
print("--------------------------------")
104+
print(answer)
105+
print("--------------------------------")
106+
finally:
107+
agent.dispose()
108+
109+
110+
if __name__ == "__main__":
111+
try:
112+
main()
113+
except Exception as e:
114+
print(f"Error: {e}", file=sys.stderr)
115+
traceback.print_exc(file=sys.stderr)
116+
sys.exit(1)

0 commit comments

Comments
 (0)