In common server scenarios, static state is shared across requests which means multiple threads could be executing that code at the same time (which opens up this possibility for threading bugs). Consider using a design pattern that encapsulates data into instances that are not shared across requests.
Design your library for the stress of running in a server scenario. Avoid taking locks if at all possible.
By default, the library is NOT thread safe. Adding locks to create thread safe code decrease perf and increase lock contention (as well as opening up dead lock bugs). In common application models, only on thread at a time is executing user code which makes the need for thread safety minimal. For this reason the frameworks are not thread safe by default. In cases where it's interesting to have a thread safe version a GetSynchronized() method can be used to return a thread safe instance of that type. (See System.Collections for examples).
If you must use static state make it thread safe. In common server scenarios, static data is shared across requests which means multiple threads could be executing that code at the same time. For this reason it is necessary to protect static state.