diff --git a/examples/cloud/oauth/mcp_tools/README.md b/examples/cloud/oauth/mcp_tools/README.md new file mode 100644 index 000000000..05201193b --- /dev/null +++ b/examples/cloud/oauth/mcp_tools/README.md @@ -0,0 +1,166 @@ +# OAuth MCP Tools Example + +This example demonstrates how to integrate OAuth 2.0-enabled MCP servers within mcp-agent. The example exposes a `github_org_search` tool that calls the GitHub MCP server, requiring OAuth authorization. + +## What's included + +- `main.py` – exposes a `github_org_search` tool that integrates with the GitHub MCP server using OAuth 2.0 +- `mcp_agent.config.yaml` – configures OAuth settings including callback URLs, flow timeout, and token store settings +- `mcp_agent.secrets.yaml.example` – template for storing GitHub OAuth credentials (client ID, secret, and access token) + +## Features + +- **Interactive (lazy) authorization**: When the tool is invoked without a cached token, the server issues an `auth/request` message and the client opens the browser to interactively complete the GitHub sign-in +- **Pre-authorized workflows**: Leverage the workflows-store-credentials mcp-agent tool to cache a token for a specified workflow before the workflow is run. Once the token is saved, the workflow can access the downstream MCP server without further user interaction +- **GitHub repository search**: Search GitHub repositories within organizations using the OAuth-protected GitHub MCP server +- **Token caching**: OAuth tokens are cached and reused across runs using a stable session ID + +## Prerequisites + +- Python 3.10+ +- [UV](https://github.com/astral-sh/uv) package manager +- GitHub OAuth App for authentication + +## Configuration + +Before running the example, you'll need to create a GitHub OAuth App and configure the credentials. + +### GitHub OAuth App Setup + +1. Create a GitHub OAuth App (Settings → Developer settings → OAuth Apps) + +2. Set the **Authorization callback URL** to `http://127.0.0.1:33418/callback` + + > The example pins its loopback listener to that port, so the value must match exactly. + +3. For testing in MCP Inspector, add an additional callback URL: `http://localhost:6274/oauth/callback` + + > [!NOTE] + > GitHub does not accept the RFC 8707 `resource` parameter, so the example disables it via `include_resource_parameter: false` in the config. + +4. Obtain a GitHub personal access token from https://github.com/settings/personal-access-tokens + +### Secrets Configuration + +1. Copy the example secrets file: + +```bash +cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml +``` + +2. Edit `mcp_agent.secrets.yaml` to add your GitHub OAuth credentials: + +```yaml +mcp: + servers: + github: + auth: + oauth: + client_id: "your-github-client-id" + client_secret: "your-github-client-secret" + access_token: "your-github-access-token" +``` + +## Test Locally + +1. Install dependencies: + +```bash +cd examples/cloud/oauth/mcp_tools +uv pip install -r requirements.txt +``` + +2. Start the mcp-agent server locally with SSE transport: + +```bash +uv run main.py +``` + +The server uses a stable session ID so the OAuth token is cached and reused across runs. Once the first authorization completes, subsequent invocations should return immediately without reopening the browser. + +3. Use [MCP Inspector](https://github.com/modelcontextprotocol/inspector) to test the OAuth-enabled MCP tools: + +```bash +npx @modelcontextprotocol/inspector --transport sse --server-url http://127.0.0.1:8000/sse +``` + +4. In MCP Inspector: + - The server will initiate the OAuth 2.0 authorization flow when you first call the `github_org_search` tool + - Complete the GitHub authorization in your browser + - Once authenticated, test the `github_org_search` tool with an organization name (e.g., "github") + - The tool will search for repositories in the specified organization and return the top 5 results + - To pre-authorize the `github_org_search` workflow, call the `workflows-store-credentials` tool with: + +```json +{ + "workflow_name": "github_org_search_activity", + "tokens": [ + { + "access_token": access_token, + "server_name": "github", + } + ] +} +``` + +## Deploy to mcp-agent Cloud + +You can deploy this OAuth-enabled MCP-Agent app as a hosted mcp-agent app in the Cloud. + +1. In your terminal, authenticate into mcp-agent cloud by running: + +```bash +uv run mcp-agent login +``` + +2. You will be redirected to the login page, create an mcp-agent cloud account through Google or Github + +3. Set up your mcp-agent cloud API Key and copy & paste it into your terminal + +```bash +uv run mcp-agent login +INFO: Directing to MCP Agent Cloud API login... +Please enter your API key 🔑: +``` + +4. In your terminal, deploy the MCP app: + +```bash +uv run mcp-agent deploy oauth-mcp-tools +``` + +5. When prompted, specify the type of secret to save your GitHub OAuth credentials. Select (1) deployment secret so that they are available to the deployed server. + +The `deploy` command will bundle the app files and deploy them, producing a server URL of the form: +`https://.deployments.mcp-agent.com`. + +## MCP Clients + +Since the mcp-agent app is exposed as an MCP server, it can be used in any MCP client that supports the MCP protocol. + +### MCP Inspector + +You can inspect and test the deployed server using [MCP Inspector](https://github.com/modelcontextprotocol/inspector): + +```bash +npx @modelcontextprotocol/inspector --transport sse --server-url https://.deployments.mcp-agent.com/sse +``` + +This will launch the MCP Inspector UI where you can: + +- Complete the OAuth 2.0 authorization flow for GitHub +- See all available tools (including `github_org_search`) +- Test the `github_org_search` tool with different organization queries + +Make sure Inspector is configured with the following settings: + +| Setting | Value | +| ---------------- | --------------------------------------------------- | +| _Transport Type_ | _SSE_ | +| _SSE_ | _https://[server_id].deployments.mcp-agent.com/sse_ | +| _Header Name_ | _Authorization_ | +| _Bearer Token_ | _your-mcp-agent-cloud-api-token_ | + +## Further Reading + +More details on OAuth authorization and the MCP protocol can be found at [https://modelcontextprotocol.io/specification/draft/basic/authorization](https://modelcontextprotocol.io/specification/draft/basic/authorization). diff --git a/examples/cloud/oauth/mcp_tools/main.py b/examples/cloud/oauth/mcp_tools/main.py new file mode 100644 index 000000000..1493cd871 --- /dev/null +++ b/examples/cloud/oauth/mcp_tools/main.py @@ -0,0 +1,95 @@ +""" +MCP Agent MCP Tools OAuth Example + +This example demonstrates how to integrate OAuth 2.0-enabled MCP servers within mcp-agent. + +1. Interactive (lazy) authorization: When the tool is invoked without a cached token, the server issues an `auth/request` message and the client opens the browser so you can complete the GitHub sign-in. + +2. Pre-authorized workflows: Leverage the workflows-store-credentials mcp-agent tool to cache a token for a specified workflow before the workflow is run. Once the token is saved, the workflow can access the downstream MCP server without further user interaction. + +""" + +import asyncio +import json +from typing import Optional + +from mcp_agent.app import MCPApp +from mcp_agent.core.context import Context as AppContext +from mcp_agent.mcp.gen_client import gen_client +from mcp_agent.server.app_server import create_mcp_server_for_app + +app = MCPApp( + name="oauth_mcp_tools", + description="Example of MCP tools with OAuth integration", +) + +# You can pre-authorize this workflow by calling workflows-store-credentials tool with: +# { +# "workflow_name": "github_org_search_activity", +# "tokens": [ +# { +# "access_token": access_token, +# "server_name": "github", +# } +# ] +# } + + +@app.workflow_task(name="github_org_search_activity") +async def github_org_search_activity(query: str) -> str: + app.logger.info("github_org_search_activity started") + try: + async with gen_client( + "github", server_registry=app.context.server_registry, context=app.context + ) as github_client: + app.logger.info("Obtained GitHub MCP client") + result = await github_client.call_tool( + "search_repositories", + { + "query": f"org:{query}", + "per_page": 5, + "sort": "best-match", + "order": "desc", + }, + ) + + repositories = [] + if result.content: + for content_item in result.content: + if hasattr(content_item, "text"): + try: + data = json.loads(content_item.text) + if isinstance(data, dict) and "items" in data: + repositories.extend(data["items"]) + elif isinstance(data, list): + repositories.extend(data) + except json.JSONDecodeError: + pass + + app.logger.info("Repositories fetched", data={"count": len(repositories)}) + return json.dumps(repositories, indent=2) + except Exception as e: + import traceback + + traceback.print_exc() + return f"Error: {e}" + + +@app.tool(name="github_org_search") +async def github_org_search(query: str, app_ctx: Optional[AppContext] = None) -> str: + context = app_ctx or app.context + result = await app.executor.execute(github_org_search_activity, query) + context.logger.info("Workflow result", data={"result": result}) + + return result + + +# NOTE: This main function is useful for local testing but will be ignored in the cloud deployment. +async def main(): + async with app.run() as agent_app: + mcp_server = create_mcp_server_for_app(agent_app) + await mcp_server.run_sse_async() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/cloud/oauth/mcp_tools/mcp_agent.config.yaml b/examples/cloud/oauth/mcp_tools/mcp_agent.config.yaml new file mode 100644 index 000000000..e026bfc4b --- /dev/null +++ b/examples/cloud/oauth/mcp_tools/mcp_agent.config.yaml @@ -0,0 +1,32 @@ +$schema: ../../schema/mcp-agent.config.schema.json + +name: my_mcp_agent_oauth_server + +execution_engine: asyncio +logger: + transports: [console] + level: debug + +oauth: + # Base URL for internal callbacks (used when `use_internal_callback` is true). + callback_base_url: http://127.0.0.1:8000 + # Maximum number of seconds to wait for an authorization callback before timing out. + flow_timeout_seconds: 300 + # Ports to use for local loopback callbacks when internal callbacks are unavailable. + loopback_ports: [33418, 33419, 33420] + token_store: + # Seconds before expiry when tokens should be refreshed. + refresh_leeway_seconds: 60 + +mcp: + servers: + github: + transport: streamable_http + url: "https://api.githubcopilot.com/mcp/" + auth: + oauth: + enabled: true + scopes: ["read:org", "public_repo", "user:email"] + authorization_server: "https://github.com/login/oauth" + use_internal_callback: false + include_resource_parameter: false diff --git a/examples/cloud/oauth/mcp_tools/mcp_agent.secrets.yaml.example b/examples/cloud/oauth/mcp_tools/mcp_agent.secrets.yaml.example new file mode 100644 index 000000000..77baa7150 --- /dev/null +++ b/examples/cloud/oauth/mcp_tools/mcp_agent.secrets.yaml.example @@ -0,0 +1,12 @@ +$schema: ../../../schema/mcp-agent.config.schema.json + +# Copy this file to mcp_agent.secrets.yaml and fill in your credentials. + +mcp: + servers: + github: + auth: + oauth: + client_id: "your-github-client-id" + client_secret: "your-github-client-secret" + access_token: "your-github-access-token" diff --git a/examples/cloud/oauth/mcp_tools/requirements.txt b/examples/cloud/oauth/mcp_tools/requirements.txt new file mode 100644 index 000000000..bb00d56c2 --- /dev/null +++ b/examples/cloud/oauth/mcp_tools/requirements.txt @@ -0,0 +1 @@ +mcp-agent @ file://../../../../ # Link to the local mcp-agent project root diff --git a/examples/cloud/oauth/server/README.md b/examples/cloud/oauth/server/README.md new file mode 100644 index 000000000..2823db46a --- /dev/null +++ b/examples/cloud/oauth/server/README.md @@ -0,0 +1,194 @@ +# OAuth Protected Server Example + +This example demonstrates how to secure an mcp-agent server with OAuth 2.0 authentication. + +## What's included + +- `main.py` – exposes a `hello_world` tool that demonstrates authenticated user access with personalized responses based on OAuth claims +- `registration.py` – helper script to dynamically register your OAuth client with an authorization server using the Dynamic Client Registration Protocol +- `mcp_agent.config.yaml` – configures authorization settings including issuer URL, required scopes, and OAuth callback settings +- `mcp_agent.secrets.yaml.example` – template for storing OAuth client credentials (client ID and secret) + +## Features + +- **OAuth 2.0 authentication**: Protects MCP server endpoints with industry-standard OAuth 2.0 authorization +- **Dynamic client registration**: Automatically registers OAuth clients following the Dynamic Client Registration Protocol +- **User context access**: Tools can access authenticated user information including claims and subject IDs +- **Flexible provider support**: Works with mcp-agent cloud auth server or your own OAuth 2.0 provider + +## Prerequisites + +- Python 3.10+ +- [UV](https://github.com/astral-sh/uv) package manager +- OAuth 2.0 provider (e.g., mcp-agent cloud auth server at https://auth.mcp-agent.com or your own) + +## Configuration + +Before running the example, you'll need to register an OAuth client and configure the server. + +### Client Registration + +If you do not have a client registered already, you can use the `registration.py` script provided with this example. + +1. First, ensure `mcp_agent.config.yaml` has the correct values for: + +- `authorization.issuer_url`: authorization server issuing the client ID and secret; by default this will be the mcp-agent cloud auth server (https://auth.mco-agent.com) +- `oauth.callback_base_url`: base URL for oauth callbacks; by default this will be the local server URL (http://localhost:8000) + +2. Install dependencies: + +```bash +cd examples/cloud/oauth/server +uv pip install -r requirements.txt +``` + +3. Run the registration script: + +```bash +uv run registration.py +``` + +The script will register your client with the authorization server (configured in `mcp_agent.config.yaml`) and output credentials: + +``` +Client registered successfully! +{ + # detailed json response +} + +=== Save these credentials === +Client ID: abc-123 +Client Secret: xyz-987 +``` + +4. Save the `Client ID` and `Client Secret` for the next step. + +> The registration script automatically configures redirect URIs for the server (as specified by `oauth.callback_base_url` in the `mcp_agent.config.yaml`) and MCP Inspector (`http://localhost:6274/oauth/callback`). For production deployments, update the `oauth.callback_base_url` in `mcp_agent.config.yaml` to match your deployment URL, e.g. `https://.deployments.mcp-agent.com`. + +### Secrets Configuration + +1. Copy the example secrets file: + +```bash +cp mcp_agent.secrets.yaml.example mcp_agent.secrets.yaml +``` + +2. Edit `mcp_agent.secrets.yaml` to add your OAuth credentials: + +```yaml +authorization: + client_id: + client_secret: + expected_audiences: + - +``` + +> The `expected_audiences` field should match your client ID to ensure tokens are issued for your application. + +## Test Locally + +1. Install dependencies: + +```bash +uv pip install -r requirements.txt +``` + +2. Start the mcp-agent server locally with SSE transport: + +```bash +uv run main.py +``` + +3. Use [MCP Inspector](https://github.com/modelcontextprotocol/inspector) to test the OAuth-protected server: + +```bash +npx @modelcontextprotocol/inspector --transport sse --server-url http://localhost:8000/sse +``` + +4. In MCP Inspector: + + - Specify Client ID and Client Secret in the OAuth 2.0 Flow Authentication section + - The server will initiate the OAuth 2.0 authorization flow + - Complete the authorization in your browser + - Once authenticated, test the `hello_world` tool + - The tool will respond with a personalized greeting using your authenticated user information + +5. Observe how the tool accesses user context: + - If a username claim is present: "Hello, [username]!" + - Otherwise: "Hello, user with ID [subject]!" + +## Deploy to mcp-agent Cloud + +You can deploy this OAuth-protected MCP-Agent app as a hosted mcp-agent app in the Cloud. + +1. In your terminal, authenticate into mcp-agent cloud by running: + +```bash +uv run mcp-agent login +``` + +2. You will be redirected to the login page, create an mcp-agent cloud account through Google or Github + +3. Set up your mcp-agent cloud API Key and copy & paste it into your terminal + +```bash +uv run mcp-agent login +INFO: Directing to MCP Agent Cloud API login... +Please enter your API key 🔑: +``` + +4. In your terminal, deploy the MCP app: + +```bash +uv run mcp-agent deploy oauth-example +``` + +5. When prompted, specify the type of secret to save your OAuth client credentials. Select (1) deployment secret so that they are available to the deployed server. + +The `deploy` command will bundle the app files and deploy them, producing a server URL of the form: +`https://.deployments.mcp-agent.com`. + +6. After initial deployment, update the authorization and oauth configuration in `mcp_agent.config.yaml` to use your deployed server URL: + +- Set `authorization.resource_server_url` to `https://.deployments.mcp-agent.com` +- Set `oauth.callback_base_url` to `https://.deployments.mcp-agent.com` + +7. Then re-run the registration script to get new credentials and set them in `mcp_agent.secrets.yaml` + +8. Finally, redeploy the server with the updated configuration + +```bash +uv run mcp-agent deploy oauth-example +``` + +## MCP Clients + +Since the mcp-agent app is exposed as an MCP server, it can be used in any MCP client that supports OAuth 2.0 authentication, just like any other OAuth-protected MCP server. + +### MCP Inspector + +You can inspect and test the deployed server using [MCP Inspector](https://github.com/modelcontextprotocol/inspector): + +```bash +npx @modelcontextprotocol/inspector --transport sse --server-url https://.deployments.mcp-agent.com/sse +``` + +This will launch the MCP Inspector UI where you can: + +- Complete the OAuth 2.0 authorization flow +- See all available tools +- Test the `hello_world` tool with your authenticated user context + +Make sure Inspector is configured with the following settings: + +| Setting | Value | +| ---------------- | --------------------------------------------------- | +| _Transport Type_ | _SSE_ | +| _SSE_ | _https://[server_id].deployments.mcp-agent.com/sse_ | + +> [!NOTE] +> When connecting with MCP Inspector, you will be redirected to complete the OAuth authorization flow in your browser before being able to use the server. + +## Further Reading + +More details on OAuth authorization and the MCP protocol can be found at [https://modelcontextprotocol.io/specification/draft/basic/authorization](https://modelcontextprotocol.io/specification/draft/basic/authorization). diff --git a/examples/cloud/oauth/server/main.py b/examples/cloud/oauth/server/main.py new file mode 100644 index 000000000..7122f3e34 --- /dev/null +++ b/examples/cloud/oauth/server/main.py @@ -0,0 +1,46 @@ +""" +MCP Agent Server OAuth Example + +This example demonstrates how to secure an MCP Agent server using OAuth 2.0. +""" + +import asyncio +from typing import Optional + +from mcp_agent.core.context import Context as AppContext + +from mcp_agent.app import MCPApp +from mcp_agent.server.app_server import create_mcp_server_for_app + + +# Define the MCPApp instance. The server created for this app will advertise the +# MCP logging capability and forward structured logs upstream to connected clients. +app = MCPApp( + name="oauth_demo", + description="Basic agent server example", +) + + +@app.tool(name="hello_world") +async def hello(app_ctx: Optional[AppContext] = None) -> str: + context = app_ctx or app.context + + if context.current_user: + user = context.current_user + if user.claims and "username" in user.claims: + return f"Hello, {user.claims['username']}!" + else: + return f"Hello, user with ID {user.subject}!" + else: + return "Hello, anonymous user!" + + +# NOTE: This main function is useful for local testing but will be ignored in the cloud deployment. +async def main(): + async with app.run() as agent_app: + mcp_server = create_mcp_server_for_app(agent_app) + await mcp_server.run_sse_async() + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/cloud/oauth/server/mcp_agent.config.yaml b/examples/cloud/oauth/server/mcp_agent.config.yaml new file mode 100644 index 000000000..8109193cb --- /dev/null +++ b/examples/cloud/oauth/server/mcp_agent.config.yaml @@ -0,0 +1,28 @@ +$schema: ../../schema/mcp-agent.config.schema.json + +name: my_mcp_agent_oauth_server + +execution_engine: asyncio +logger: + transports: [console] + level: debug + +authorization: + enabled: true + # Issuer URL advertised to clients (must resolve to provider metadata) + issuer_url: https://auth.mcp-agent.com + # Base URL of the protected resource (used for discovery and validation). + # i.e. this server URL. + resource_server_url: http://localhost:8000 + # Scopes that clients must present when accessing this resource. + required_scopes: [mcp] + # client_id and client_secret are provided via mcp_agent.secrets.yaml + +oauth: + # Base URL for internal callbacks (used when `use_internal_callback` is true). + callback_base_url: http://localhost:8000 + # Maximum number of seconds to wait for an authorization callback before timing out. + flow_timeout_seconds: 300 + token_store: + # Seconds before expiry when tokens should be refreshed. + refresh_leeway_seconds: 60 diff --git a/examples/cloud/oauth/server/mcp_agent.secrets.yaml.example b/examples/cloud/oauth/server/mcp_agent.secrets.yaml.example new file mode 100644 index 000000000..7f26f43e3 --- /dev/null +++ b/examples/cloud/oauth/server/mcp_agent.secrets.yaml.example @@ -0,0 +1,6 @@ + +authorization: + client_id: + client_secret: + expected_audiences: + - diff --git a/examples/cloud/oauth/server/registration.py b/examples/cloud/oauth/server/registration.py new file mode 100644 index 000000000..269536bf5 --- /dev/null +++ b/examples/cloud/oauth/server/registration.py @@ -0,0 +1,63 @@ +import json + +import requests +from main import app + +# Authorization server URL. This can either be the mcp-agent cloud authorization server (as currently configured), +# or your own. +auth_server_url = app.config.authorization.issuer_url + +redirect_uris = [ + # MCP Server redirect URIs + f"{app.config.oauth.callback_base_url}/callback", + f"{app.config.oauth.callback_base_url}/callback/debug", + # MCP Inspector redirect URIs (for testing with MCP Inspector) + "http://localhost:6274/oauth/callback", + "http://localhost:6274/oauth/callback/debug", +] + +# Fetch the registration endpoint dynamically from the .well-known/oauth-authorization-server details +well_known_url = f"{auth_server_url}/.well-known/oauth-authorization-server" +response = requests.get(well_known_url, timeout=10) + +if response.status_code == 200: + well_known_details = response.json() + registration_endpoint = well_known_details.get("registration_endpoint") + if not registration_endpoint: + raise ValueError("Registration endpoint not found in .well-known details") +else: + raise ValueError(f"Failed to fetch .well-known details: {response.status_code}") + + +# Client registration request +registration_request = { + "client_name": app.config.name, + "redirect_uris": redirect_uris, + "grant_types": ["authorization_code", "refresh_token"], + "scope": "mcp", + # use client_secret_basic when testing with MCP Inspector + "token_endpoint_auth_method": "client_secret_basic", +} + +print(f"Registering client at: {registration_endpoint}") + +# Register the client +response = requests.post( + registration_endpoint, + json=registration_request, + headers={"Content-Type": "application/json"}, + timeout=60, +) + +if response.status_code in [200, 201]: + client_info = response.json() + print("Client registered successfully!") + print(json.dumps(client_info, indent=2)) + + # Save credentials for later use + print("\n=== Save these credentials ===") + print(f"Client ID: {client_info['client_id']}") + print(f"Client Secret: {client_info['client_secret']}") +else: + print(f"Registration failed with status {response.status_code}") + print(response.text) diff --git a/examples/cloud/oauth/server/requirements.txt b/examples/cloud/oauth/server/requirements.txt new file mode 100644 index 000000000..bb00d56c2 --- /dev/null +++ b/examples/cloud/oauth/server/requirements.txt @@ -0,0 +1 @@ +mcp-agent @ file://../../../../ # Link to the local mcp-agent project root diff --git a/examples/oauth/pre_authorize/README.md b/examples/oauth/pre_authorize/README.md index 19dbbea0d..63adc560f 100644 --- a/examples/oauth/pre_authorize/README.md +++ b/examples/oauth/pre_authorize/README.md @@ -16,8 +16,7 @@ workflow can access the downstream MCP server without further user interaction. Edit the copied file (or export matching environment variables) so the GitHub entry contains your OAuth app's client id and client secret. -2. Obtain a GitHub access token (e.g., via the interactive example) and - export it before running the client: +2. Obtain a GitHub access token (e.g., via the interactive example or from https://github.com/settings/personal-access-tokens) and export it before running the client: ```bash export GITHUB_ACCESS_TOKEN="github_pat_xxx" @@ -41,18 +40,47 @@ workflow can access the downstream MCP server without further user interaction. ## Running -1. Start the workflow server: +Before running this example, you need to have a Temporal server running: - ```bash - python examples/oauth/pre_authorize/main.py - ``` +1. Install the Temporal CLI by following the instructions at: https://docs.temporal.io/cli/ + +2. In a separate terminal, start a local Temporal server: + +```bash +temporal server start-dev +``` + +This will start a Temporal server on `localhost:7233` (the default address configured in `mcp_agent.config.yaml`). + +You can use the Temporal Web UI to monitor your workflows by visiting `http://localhost:8233` in your browser. + +3. In a second terminal: + +Install the required dependencies: -2. In another terminal, run the client to seed the token and execute the +```bash +cd examples/oauth/pre_authorize +uv pip install -r requirements.txt +``` + +Start the temporal worker: + +```bash +uv run worker.py +``` + +4. In a third terminal, start the workflow server: + +```bash +python examples/oauth/pre_authorize/main.py +``` + +5. In another terminal, run the client to seed the token and execute the workflow: - ```bash - python examples/oauth/pre_authorize/client.py - ``` +```bash +python examples/oauth/pre_authorize/client.py +``` The client first invokes `workflows-store-credentials` with the provided token and then calls the `github_org_search` workflow, which uses the cached token to diff --git a/examples/oauth/pre_authorize/mcp_agent.secrets.yaml.example b/examples/oauth/pre_authorize/mcp_agent.secrets.yaml.example index 95509475c..77baa7150 100644 --- a/examples/oauth/pre_authorize/mcp_agent.secrets.yaml.example +++ b/examples/oauth/pre_authorize/mcp_agent.secrets.yaml.example @@ -10,4 +10,3 @@ mcp: client_id: "your-github-client-id" client_secret: "your-github-client-secret" access_token: "your-github-access-token" - diff --git a/examples/oauth/pre_authorize/requirements.txt b/examples/oauth/pre_authorize/requirements.txt new file mode 100644 index 000000000..2fa590b39 --- /dev/null +++ b/examples/oauth/pre_authorize/requirements.txt @@ -0,0 +1,6 @@ +# Core framework dependency +mcp-agent @ file://../../../ # Link to the local mcp-agent project root + +# Additional dependencies specific to this example +openai +temporalio