|
1 | | -# Topcoder Model Context Protocol (MCP) Server |
2 | | - |
3 | | -## Authentication Based Access via Guards |
4 | | - |
5 | | -Tools/Resources/Prompts support authentication via TC JWT and/or M2M JWT. Providing JWT in the requests to the MCP server will result in specific listings and bahavior based on JWT access level/roles/permissions. |
6 | | - |
7 | | -#### Using `authGuard` - requires TC jwt presence for access |
8 | | - |
9 | | -```ts |
10 | | - @Tool({ |
11 | | - name: 'query-tc-challenges-private', |
12 | | - description: |
13 | | - 'Returns a list of Topcoder challenges based on the query parameters.', |
14 | | - parameters: QUERY_CHALLENGES_TOOL_PARAMETERS, |
15 | | - outputSchema: QUERY_CHALLENGES_TOOL_OUTPUT_SCHEMA, |
16 | | - annotations: { |
17 | | - title: 'Query Public Topcoder Challenges', |
18 | | - readOnlyHint: true, |
19 | | - }, |
20 | | - canActivate: authGuard, |
21 | | - }) |
22 | | -``` |
23 | | - |
24 | | -#### Using `checkHasUserRole(Role.Admin)` - TC Role based guard |
25 | | - |
26 | | -```ts |
27 | | - @Tool({ |
28 | | - name: 'query-tc-challenges-protected', |
29 | | - description: |
30 | | - 'Returns a list of Topcoder challenges based on the query parameters.', |
31 | | - parameters: QUERY_CHALLENGES_TOOL_PARAMETERS, |
32 | | - outputSchema: QUERY_CHALLENGES_TOOL_OUTPUT_SCHEMA, |
33 | | - annotations: { |
34 | | - title: 'Query Public Topcoder Challenges', |
35 | | - readOnlyHint: true, |
36 | | - }, |
37 | | - canActivate: checkHasUserRole(Role.Admin), |
38 | | - }) |
39 | | -``` |
40 | | - |
41 | | -#### Using `canActivate: checkM2MScope(M2mScope.QueryPublicChallenges)` - M2M based access via scopes |
42 | | - |
43 | | -```ts |
44 | | - @Tool({ |
45 | | - name: 'query-tc-challenges-m2m', |
46 | | - description: |
47 | | - 'Returns a list of Topcoder challenges based on the query parameters.', |
48 | | - parameters: QUERY_CHALLENGES_TOOL_PARAMETERS, |
49 | | - outputSchema: QUERY_CHALLENGES_TOOL_OUTPUT_SCHEMA, |
50 | | - annotations: { |
51 | | - title: 'Query Public Topcoder Challenges', |
52 | | - readOnlyHint: true, |
53 | | - }, |
54 | | - canActivate: checkM2MScope(M2mScope.QueryPublicChallenges), |
55 | | - }) |
| 1 | +# Microsoft Teams AI Agent |
| 2 | + |
| 3 | +A production-grade Microsoft Teams Tab app featuring a conversational AI agent powered by **LangChain.js** and **AWS Bedrock**. |
| 4 | +The agent integrates with mcp tools to answer real-time queries beyond its base model knowledge. |
| 5 | + |
| 6 | +--- |
| 7 | + |
| 8 | +## ✨ Key Features |
| 9 | + |
| 10 | +* **Conversational AI:** Powered by LangChain.js + AWS Bedrock (Claude 3.5 Sonnet). |
| 11 | +* **External Tools:** Fetch live contextual data through external integrations. |
| 12 | +* **Real-time Chat Streaming:** Uses SSE for continuous agent thought updates. |
| 13 | +* **Conversation History:** Stored and grouped in MongoDB for persistence. |
| 14 | +* **Azure AD SSO:** Secure Teams authentication for verified access. |
| 15 | +* **Fluent UI + Teams SDK:** Seamless user experience inside Teams. |
| 16 | +* **Flexible Deployment:** Manual dev setup + production-ready Docker build. |
| 17 | + |
| 18 | +--- |
| 19 | + |
| 20 | +## 🧩 Technology Stack |
| 21 | + |
| 22 | +| Frontend (Vite) | Backend (Node.js + Express) | |
| 23 | +| --------------------------- | ----------------------------------------- | |
| 24 | +| ✅ React + TypeScript (Vite) | ✅ LangChain.js + AWS Bedrock (Claude 3.5) | |
| 25 | +| ✅ Fluent UI + Teams SDK | ✅ MongoDB (Mongoose ODM) | |
| 26 | +| ✅ Vite environment support | ✅ MCP Gateway for tool access | |
| 27 | + |
| 28 | +| AI & Security | Infrastructure | |
| 29 | +| --------------------------------- | --------------------------------- | |
| 30 | +| ✅ AWS Bedrock (Claude 3.5 Sonnet) | ✅ Docker-based production build | |
| 31 | +| ✅ Azure Active Directory (SSO) | ✅ Environment-based configuration | |
| 32 | +| ✅ JWT Validation + JWKS-RSA | ✅ ngrok for local Teams testing | |
| 33 | + |
| 34 | +--- |
| 35 | + |
| 36 | +## 🧠 Local Development Setup (Manual) |
| 37 | + |
| 38 | +You can run the frontend and backend separately for local testing. |
| 39 | +This is the preferred approach during active development. |
| 40 | + |
| 41 | +## Prerequisites |
| 42 | + |
| 43 | +* **Node.js:** v22.x |
| 44 | +* **MongoDB:** Local instance or MongoDB Atlas |
| 45 | +* **ngrok:** To expose your servers for Teams testing |
| 46 | +* **[Azure AD App Registration: For SSO](./docs/AzureConfig.md)** |
| 47 | +* **AWS Bedrock access** |
| 48 | + |
| 49 | +### Step 1: Clone Repository |
| 50 | + |
| 51 | +```bash |
| 52 | +git clone https://github.com/topcoder-platform/tc-mcp.git |
| 53 | +cd tc-mcp |
| 54 | +``` |
| 55 | + |
| 56 | +--- |
| 57 | + |
| 58 | +### Step 2: Backend Setup |
| 59 | + |
| 60 | +```bash |
| 61 | +pnpm install |
| 62 | +cp .env.example .env |
| 63 | +# Edit .env with MongoDB, Azure, AWS credentials, Frontend env too |
| 64 | +pnpm start:dev |
56 | 65 | ``` |
| 66 | + |
| 67 | +Backend will run at `http://localhost:3000/v6/mcp/*`. |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +### Step 3: Frontend Setup |
| 72 | + |
| 73 | +```bash |
| 74 | +cd teamsTab |
| 75 | +pnpm install |
| 76 | +pnpm run dev |
| 77 | +``` |
| 78 | + |
| 79 | +Frontend will run at `http://localhost:5173/teamsTab`. |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +### Step 4: Expose Local Servers for Teams |
| 84 | + |
| 85 | +To test inside Teams, both servers must be public. It's best to get static url from ngrok for frontend, So we can setup Azure AD, MS Teams app with this static url once, and also prefer to take static url for backend too. |
| 86 | + |
| 87 | +```bash |
| 88 | +# For frontend |
| 89 | +ngrok http --url=your-ngrok-static-url-frontend.app 5173 |
| 90 | +# For backend |
| 91 | +ngrok http 3000 |
| 92 | +``` |
| 93 | + |
| 94 | +You’ll get two public URLs: |
| 95 | + |
| 96 | +* Frontend → `https://your-ngrok-static-url-frontend.app` |
| 97 | +* Backend → `https://<backend-id>.ngrok-free.app` |
| 98 | + |
| 99 | +> **Note:** |
| 100 | +> * ngrok frontend url should be added to `teamsTab\vite.config.ts` allowed hosts for development environment. |
| 101 | +> * ngrok backend url should be added to `.env` for `VITE_API_BASE_URL` development |
| 102 | +- Example: `VITE_API_BASE_URL=https://<backend-id>.ngrok-free.app/v6/mcp/agent` |
| 103 | +
|
| 104 | +--- |
| 105 | + |
| 106 | +### Step 5: Configure Teams Manifest |
| 107 | + |
| 108 | +Edit: |
| 109 | + |
| 110 | +``` |
| 111 | +teamsTab/appPackageDev/manifest.json |
| 112 | +``` |
| 113 | + |
| 114 | +### Read: [MsTeamsConfig.md](./MsTeamsConfig.md) |
| 115 | + |
| 116 | + |
| 117 | +--- |
| 118 | + |
| 119 | +### Step 6: Sideload App in Teams |
| 120 | + |
| 121 | +1. Zip the following from `teamsTab/appPackageDev/`: |
| 122 | + |
| 123 | + * `manifest.json` |
| 124 | + * `color.png` |
| 125 | + * `outline.png` |
| 126 | +2. Go to **Microsoft Teams → Apps → Upload a custom app** and upload the zip. |
| 127 | + |
| 128 | +You can now test the full AI agent directly in the Teams client. |
| 129 | + |
| 130 | +--- |
| 131 | + |
| 132 | +# 🐳 Production / Deployment (Dockerized) |
| 133 | + |
| 134 | +When you’re ready to deploy (e.g., on **Railway**, **Render**, or **AWS ECS**), use the provided `Dockerfile`. |
| 135 | + |
| 136 | +### Dockerfile Overview |
| 137 | + |
| 138 | +* Installs dependencies |
| 139 | +* Builds the frontend (`teamsTab/`) |
| 140 | +* Builds the backend |
| 141 | +* Starts the server using `appStartUp.sh` |
| 142 | +* Frontend & Backend Agent will be available in single url |
| 143 | + - http://localhost:3000/teamsTab - Frontend for MS Teams app |
| 144 | + - http://localhost:3000/v6/mcp/agent - Backend Agent for frontend |
| 145 | + - http://localhost:3000/v6/mcp/* - Other Backend endpoints - `/mcp`, `/sse` etc |
| 146 | + |
| 147 | + |
| 148 | +### Build and Run |
| 149 | + |
| 150 | +```bash |
| 151 | +docker build -t teams-ai-agent . |
| 152 | +docker run -d -p 3000:3000 teams-ai-agent |
| 153 | +``` |
| 154 | + |
| 155 | +> **Note:** |
| 156 | +> * Configure environment variables **directly in your hosting platform’s dashboard**, such as **Railway**, **AWS ECS / Lightsail**, or **Render** — no `.env` file needed. |
| 157 | +> * Most CI/CD platforms automatically include environment variables for required build arguments when running the Docker build. |
| 158 | +> |
| 159 | +> - For example, the build command would be like: |
| 160 | +> `docker build --build-arg VITE_API_BASE_URL="https://api.topcoder.com/v6/mcp/agent" -t teams-ai-agent .` |
| 161 | +> |
| 162 | +> * |
| 163 | +> **💡 Note:** |
| 164 | +> * Local docker build will use root .env since it is not added to `.dockerignore`, |
| 165 | +> * So no need to pass VITE_API_BASE_URL as Arg at `docker build -t teams-ai-agent .` |
| 166 | +
|
| 167 | +--- |
| 168 | + |
| 169 | + |
| 170 | +### Optional: ngrok for Local Preview in Docker |
| 171 | + |
| 172 | +You can still run: |
| 173 | + |
| 174 | +```bash |
| 175 | +ngrok http --url=your-ngrok-static-url-frontend.app 3000 |
| 176 | +``` |
| 177 | + |
| 178 | +And use that public URL in your Teams manifest for quick cloud-like testing. |
| 179 | + |
| 180 | +--- |
| 181 | +### Read: [AzureConfig.md](./docs/AzureConfig.md), [MsTeamsConfig.md](./docs/MsTeamsConfig.md) |
| 182 | + |
| 183 | +### Summary |
| 184 | + |
| 185 | +| Mode | How to Run | Notes | |
| 186 | +| -------------- | ---------------------------------------------- | --------------------------------------------- | |
| 187 | +| **Local Dev** | frontend + backend separately | Fast iteration, live reload | |
| 188 | +| **Production** | `docker build && docker run` | Uses built Vite files, NestJS will serve frontend | |
| 189 | +| **Teams Test** | Use ngrok URLs | Needed for Teams to access your local servers | |
| 190 | + |
0 commit comments