|
1 | 1 | # Biological Species MCP Server |
2 | 2 |
|
3 | | -A Model Context Protocol (MCP) server demonstrating enterprise-ready resource access patterns for Microsoft Copilot Studio. |
4 | | - |
5 | | -## Key Concept: Tool-Mediated Resource Access |
6 | | - |
7 | | -**Important**: Copilot Studio's orchestrator does **not directly call MCP resources**. Resources must be returned through tool calls. |
8 | | - |
9 | | -### Why This Pattern? |
10 | | - |
11 | | -In enterprise scenarios, MCP servers often expose large numbers of resources. Rather than forcing the orchestrator to enumerate and filter through all of them, we use tools to mediate access and return the right resource based on context. Search is one way to do this, but tools can use any logic—filtering by category, user permissions, recency, or business rules—to determine which resource to return. |
12 | | - |
13 | | -**How the code works:** |
14 | | - |
15 | | -First, we register resources dynamically: |
16 | | -```typescript |
17 | | -// Register each species as a resource |
18 | | -SPECIES_RESOURCES.forEach((species) => { |
19 | | - server.registerResource( |
20 | | - species.id, |
21 | | - `species:///${species.id}`, |
22 | | - { |
23 | | - title: `${species.commonName} (${species.scientificName})`, |
24 | | - description: species.description, |
25 | | - mimeType: 'text/plain' |
26 | | - }, |
27 | | - async (uri) => ({ |
28 | | - contents: [{ |
29 | | - uri: uri.href, |
30 | | - text: formatSpeciesText(species) |
31 | | - }] |
32 | | - }) |
33 | | - ); |
34 | | -}); |
35 | | -``` |
| 3 | +An MCP server demonstrating resource discovery through tools. Copilot Studio always accesses resources through tools, not directly - a design motivated by enterprise environments with large-scale resource catalogs. |
| 4 | + |
| 5 | +## Architecture |
| 6 | + |
| 7 | +**How Copilot Studio accesses MCP resources:** |
| 8 | +- Copilot Studio uses tools to discover resources (never enumerates all resources directly) |
| 9 | +- Tools return filtered resource references (e.g., search returns 5 matches) |
| 10 | +- Agent evaluates references and selectively reads chosen resources |
| 11 | +- Design enables scalability for enterprise systems with large resource catalogs |
| 12 | + |
| 13 | +**Note:** The MCP protocol supports direct resource enumeration, but Copilot Studio's architecture always uses tool-based discovery. |
| 14 | + |
| 15 | +This server implements a simple search pattern with fuzzy matching. |
| 16 | + |
| 17 | +## Available Tools |
| 18 | + |
| 19 | +- **`searchSpeciesData`** - Fuzzy search returning up to 5 matching resource references |
| 20 | +- **`listSpecies`** - Returns JSON array of all species (id, commonName, scientificName, conservationStatus) |
| 21 | + |
| 22 | +## Available Resources |
| 23 | + |
| 24 | +- 5 species with text overviews and images |
| 25 | +- 8 total resources (5 text, 3 images) |
36 | 26 |
|
37 | | -Then, our search tool returns [resource links](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#resource-links) to guide the agent: |
38 | | -```typescript |
39 | | -server.tool("searchSpecies", ..., async ({ searchTerms }) => { |
40 | | - const results = fuse.search(searchTerms); |
41 | | - const species = results[0].item; |
42 | | - |
43 | | - // Return resource link |
44 | | - return { |
45 | | - content: [{ |
46 | | - type: "resource", |
47 | | - resource: { |
48 | | - uri: `species:///${species.id}`, |
49 | | - mimeType: "text/plain", |
50 | | - text: formatSpeciesText(species) |
51 | | - } |
52 | | - }] |
53 | | - }; |
54 | | -}); |
| 27 | +``` |
| 28 | +src/ |
| 29 | +├── index.ts # Server entry point |
| 30 | +├── types.ts # TypeScript types |
| 31 | +├── data/ |
| 32 | +│ ├── species.ts # Species data (5 species) |
| 33 | +│ └── resources.ts # Resource definitions (8 resources) |
| 34 | +├── assets/ # PNG images |
| 35 | +└── utils/ # Utilities (datetime, formatting, image encoding) |
55 | 36 | ``` |
56 | 37 |
|
57 | 38 | ## Quick Start |
58 | 39 |
|
59 | | -### 1. Install & Build |
| 40 | +### Prerequisites |
| 41 | + |
| 42 | +- Node.js 18+ |
| 43 | +- [Dev Tunnels CLI](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started) |
| 44 | +- Copilot Studio access |
| 45 | + |
| 46 | +### 1. Install and Build |
| 47 | + |
60 | 48 | ```bash |
61 | 49 | npm install |
62 | 50 | npm run build |
| 51 | +``` |
| 52 | + |
| 53 | +### 2. Start Server |
| 54 | + |
| 55 | +```bash |
63 | 56 | npm start |
| 57 | +# or |
| 58 | +npm run dev |
64 | 59 | ``` |
65 | 60 |
|
66 | | -### 2. Create Dev Tunnel (Anonymous) |
| 61 | +Server runs on `http://localhost:3000/mcp` |
| 62 | + |
| 63 | +### 3. Create Dev Tunnel |
67 | 64 |
|
68 | | -**VS Code (Recommended):** |
69 | | -1. Open Ports panel (View → Terminal → Ports) |
70 | | -2. Forward port 3000 |
71 | | -3. Set visibility to **Public** |
72 | | -4. Copy the HTTPS URL |
| 65 | +**VS Code:** |
| 66 | +1. Ports panel → Forward Port → 3000 |
| 67 | +2. Right-click → Port Visibility → Public |
| 68 | +3. Copy HTTPS URL |
73 | 69 |
|
74 | | -**Or via CLI:** |
| 70 | +**CLI:** |
75 | 71 | ```bash |
76 | 72 | devtunnel host -p 3000 --allow-anonymous |
77 | 73 | ``` |
78 | 74 |
|
79 | | -### 3. Configure Copilot Studio |
80 | | - |
81 | | -1. Go to [Copilot Studio](https://copilotstudio.microsoft.com) |
82 | | -2. Open your agent |
83 | | -3. Navigate to **Tools** → **+ Add a tool** |
84 | | -4. Select **New tool** → **Model Context Protocol** |
85 | | -5. In the MCP onboarding wizard, enter: |
86 | | - - **Server name:** `Biological Species MCP` |
87 | | - - **Server description:** |
88 | | - ``` |
89 | | - MCP server providing search capabilities for biological species information |
90 | | - including habitat, diet, conservation status, and interesting facts. |
91 | | - Supports fuzzy keyword search. |
92 | | - ``` |
93 | | - - **Server URL:** `https://your-tunnel-url-3000.devtunnels.ms/mcp` |
94 | | - |
95 | | - > [!IMPORTANT] |
96 | | - > **⚠️ Double-check your tunnel URL format!** |
97 | | - > |
98 | | - > ✅ **CORRECT:** `https://abc123-3000.devtunnels.ms/mcp` |
99 | | - > ❌ **WRONG:** `https://abc123.devtunnels.ms:3000/mcp` |
100 | | - > |
101 | | - > If you use the wrong format, the connection will fail. The port must be embedded in the hostname with a hyphen. |
102 | | -
|
103 | | -6. **Authentication type:** Select **None** |
104 | | -7. Click **Create** |
105 | | -
|
106 | | -
|
107 | | -## Example Usage |
108 | | -
|
109 | | -**User:** |
110 | | -``` |
111 | | -search for info on pandas |
112 | | -``` |
| 75 | +**Important:** URL format is `https://abc123-3000.devtunnels.ms/mcp` (port in hostname with hyphen, not colon) |
113 | 76 |
|
114 | | -The agent calls `searchSpecies("pandas")` → Returns Red Panda resource → Agent responds: |
| 77 | +### 4. Configure Copilot Studio |
115 | 78 |
|
116 | | -``` |
117 | | -Red Panda (Ailurus fulgens) |
118 | | -The red panda is a small arboreal mammal native to the eastern Himalayas... |
119 | | -Conservation Status: Endangered |
120 | | -``` |
| 79 | +1. Navigate to Tools → Add tool → Model Context Protocol |
| 80 | +2. Configure: |
| 81 | + - **Server URL:** `https://your-tunnel-3000.devtunnels.ms/mcp` |
| 82 | + - **Authentication:** None |
| 83 | +3. Click Create |
| 84 | + |
| 85 | +## Example Queries |
121 | 86 |
|
122 | | -**User:** |
123 | | -``` |
124 | | -what about sharks? |
125 | 87 | ``` |
| 88 | +What species do you have? |
| 89 | +→ Calls listSpecies() |
126 | 90 |
|
127 | | -The agent calls `searchSpecies("sharks")` → Returns Great White Shark resource → Agent responds: |
| 91 | +Tell me about butterflies |
| 92 | +→ Calls searchSpeciesData("butterflies") → Returns Monarch Butterfly resources |
128 | 93 |
|
| 94 | +Show me a blue whale photo |
| 95 | +→ Calls searchSpeciesData("blue whale photo") → Returns image resource |
129 | 96 | ``` |
130 | | -Great White Shark (Carcharodon carcharias) |
131 | | -The world's largest predatory fish. These apex predators can grow up to 6 meters... |
132 | | -Conservation Status: Vulnerable |
133 | | -``` |
134 | 97 |
|
| 98 | +## Development |
| 99 | + |
| 100 | +### Adding Species |
| 101 | + |
| 102 | +1. Add to `src/data/species.ts` |
| 103 | +2. Add PNG to `src/assets/` |
| 104 | +3. Add resources to `src/data/resources.ts` |
| 105 | +4. Rebuild: `npm run build` |
135 | 106 |
|
136 | | -## License |
| 107 | +## Resources |
137 | 108 |
|
138 | | -MIT |
| 109 | +- [Model Context Protocol](https://modelcontextprotocol.io/) |
| 110 | +- [MCP SDK](https://github.com/modelcontextprotocol/typescript-sdk) |
| 111 | +- [MCP in Copilot Studio][(https://copilotstudio.microsoft.com](https://learn.microsoft.com/en-us/microsoft-copilot-studio/agent-extend-action-mcp)) |
| 112 | +- [Dev Tunnels](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/overview) |
0 commit comments